home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / tex / ptf12.zip / PTFBODY.SRC < prev    next >
Text File  |  1990-05-12  |  176KB  |  6,277 lines

  1. --::::::::::
  2. --clp_body.a
  3. --::::::::::
  4. -- **********************************************
  5. -- *                                            *
  6. -- * COMMAND_LINE_PROCESSOR                     * BODY
  7. -- *                                            *
  8. -- **********************************************
  9. with CLI;          -- from CLI2.SRC
  10. with TEXT_IO;
  11. package body COMMAND_LINE_PROCESSOR is
  12.  
  13.     NUMBER_OF_FILE_NAME_TOKENS : NATURAL;
  14.     INIT_DONE                  : BOOLEAN := FALSE;
  15.     OUTPUT_FILE_EXISTS         : BOOLEAN := FALSE;
  16.  
  17.     type FNAME (LEN : NATURAL);
  18.     type FNAME_POINTER is access FNAME;
  19.     type FNAME (LEN : NATURAL) is 
  20.        record
  21.           NAME : STRING (1 .. LEN);
  22.           NEXT : FNAME_POINTER;
  23.        end record;
  24.       
  25.     FIRST_FILE   : FNAME_POINTER := null;
  26.     CURRENT_FILE : FNAME_POINTER := null;
  27.     LAST_FILE    : FNAME_POINTER := null;
  28.       
  29.     -- ...........................................
  30.     -- .                                         .
  31.     -- . ADD_FILE_NAME                           . SPEC & BODY
  32.     -- .                                         .
  33.     -- ...........................................
  34.     procedure ADD_FILE_NAME (FILE_NAME : in STRING) is
  35.     --| Purpose
  36.     --| ADD_FILE_NAME adds the named file to the file list, building
  37.     --| onto a linked-list.  If FILE_NAME is an include file,
  38.     --| all files named by this include file and the include files
  39.     --| it references are added to the list.
  40.     --|
  41.     --| Notes
  42.     --| ADD_FILE_NAME is recursive.
  43.  
  44.       FD : TEXT_IO.FILE_TYPE;
  45.       type INLINE is 
  46.         record
  47.           CONTENT : STRING (1 .. MAX_FILE_NAME_LENGTH);
  48.           LAST    : NATURAL;
  49.         end record;
  50.       FILE : INLINE;
  51.       
  52.       -- ...........................................
  53.       -- .                                         .
  54.       -- . ADD_FILE_NAME.IS_COMMENT                . SPEC & BODY
  55.       -- .                                         .
  56.       -- ...........................................
  57.       function IS_COMMENT (ITEM : in INLINE) return BOOLEAN is
  58.       --| Purpose
  59.       --| Determine if the indicated ITEM is a comment line
  60.       --| (begins with a "--").
  61.       begin
  62.         return ITEM.LAST > 1 and then ITEM.CONTENT(1..2) = "--";
  63.       end IS_COMMENT;
  64.  
  65.       -- ...........................................
  66.       -- .                                         .
  67.       -- . ADD_FILE_NAME.ADD_NAME_TO_LIST          . SPEC & BODY
  68.       -- .                                         .
  69.       -- ...........................................
  70.       procedure ADD_NAME_TO_LIST (FILE_NAME : in STRING) is
  71.       --| Purpose
  72.       --| Add the indicated FILE_NAME to the linked list.
  73.         TEMP : FNAME_POINTER;
  74.       begin
  75.         begin
  76.           TEMP      := new FNAME (FILE_NAME'LENGTH);
  77.           TEMP.NAME := FILE_NAME;
  78.           TEMP.NEXT := null;  -- not necessary, but clear
  79.         exception
  80.           when others => raise ALLOCATION_PROBLEM;
  81.         end;
  82.         if FIRST_FILE = null then
  83.           FIRST_FILE      := TEMP;
  84.           LAST_FILE       := FIRST_FILE;
  85.           CURRENT_FILE    := FIRST_FILE;
  86.         else
  87.           LAST_FILE.NEXT := TEMP;
  88.           LAST_FILE      := TEMP;
  89.         end if;
  90.       end ADD_NAME_TO_LIST;
  91.       
  92.     begin -- ADD_FILE_NAME
  93.       if FILE_NAME (FILE_NAME'FIRST) /= INCLUDE_FILE_PREFIX then
  94.         ADD_NAME_TO_LIST (FILE_NAME);
  95.       else
  96.  
  97.         -- Process include file
  98.         begin
  99.           TEXT_IO.OPEN (FD, TEXT_IO.IN_FILE, 
  100.                         FILE_NAME (FILE_NAME'FIRST + 1 .. FILE_NAME'LAST));
  101.         exception
  102.           when others   =>
  103.             raise INCLUDE_FILE_NOT_FOUND;
  104.         end;
  105.          
  106.         -- Loop through file
  107.         while not TEXT_IO.END_OF_FILE (FD) loop
  108.           TEXT_IO.GET_LINE (FD, FILE.CONTENT, FILE.LAST);
  109.           if FILE.LAST > 0 and then not IS_COMMENT(FILE) then
  110.             if FILE.CONTENT (1) = INCLUDE_FILE_PREFIX then
  111.               ADD_FILE_NAME (FILE.CONTENT (1 .. FILE.LAST));
  112.             else
  113.               ADD_NAME_TO_LIST (FILE.CONTENT (1 .. FILE.LAST));
  114.             end if;
  115.           end if;
  116.         end loop;
  117.          
  118.         -- Close include file
  119.         TEXT_IO.CLOSE (FD);
  120.       end if;
  121.       
  122.     exception
  123.       when INCLUDE_FILE_NOT_FOUND | ALLOCATION_PROBLEM => raise;
  124.       when others    => raise UNEXPECTED_ERROR;
  125.     end ADD_FILE_NAME;
  126.    
  127.     -- ..............................................
  128.     -- .                                            .
  129.     -- . INITIALIZE                                 . BODY
  130.     -- .                                            .
  131.     -- ..............................................
  132.     procedure INITIALIZE (PROGRAM_NAME : in STRING;
  133.                           COMMAND_KIND : in COMMAND_LINE_LAYOUT
  134.                                          := ONE_OUTPUT_FILE) is
  135.     begin
  136.         if COMMAND_KIND = ONE_OUTPUT_FILE then
  137.             CLI.INITIALIZE(PROGRAM_NAME,
  138.                        "Enter input file names and output file name: ");
  139.             NUMBER_OF_FILE_NAME_TOKENS := CLI.ARGC - 1;
  140.             for I in 1 .. NUMBER_OF_FILE_NAME_TOKENS - 1 loop
  141.                 ADD_FILE_NAME(CLI.ARGV(I));
  142.             end loop;
  143.             OUTPUT_FILE_EXISTS := TRUE;
  144.         else
  145.             CLI.INITIALIZE(PROGRAM_NAME,
  146.                        "Enter input file names: ");
  147.             NUMBER_OF_FILE_NAME_TOKENS := CLI.ARGC - 1;
  148.             for I in 1 .. NUMBER_OF_FILE_NAME_TOKENS loop
  149.                 ADD_FILE_NAME(CLI.ARGV(I));
  150.             end loop;
  151.             OUTPUT_FILE_EXISTS := FALSE;
  152.         end if;
  153.         INIT_DONE := TRUE;
  154.     exception
  155.         when ALLOCATION_PROBLEM => raise;
  156.         when others             => raise UNEXPECTED_ERROR;
  157.     end INITIALIZE;
  158.  
  159.     -- ..............................................
  160.     -- .                                            .
  161.     -- . RESET                                      . BODY
  162.     -- .                                            .
  163.     -- ..............................................
  164.     procedure RESET is
  165.     begin
  166.         if not INIT_DONE then
  167.             raise INIT_ERROR;
  168.         else
  169.             CURRENT_FILE := FIRST_FILE;
  170.         end if;
  171.     exception
  172.         when INIT_ERROR => raise;
  173.         when others     => raise UNEXPECTED_ERROR;
  174.     end RESET;
  175.  
  176.     -- ..............................................
  177.     -- .                                            .
  178.     -- . IS_END                                     . BODY
  179.     -- .                                            .
  180.     -- ..............................................
  181.     function IS_END return BOOLEAN is
  182.     begin
  183.         if not INIT_DONE then
  184.             raise INIT_ERROR;
  185.         else
  186.             return CURRENT_FILE = null;
  187.         end if;
  188.     exception
  189.         when INIT_ERROR => raise;
  190.         when others     => raise UNEXPECTED_ERROR;
  191.     end IS_END;
  192.  
  193.     -- ..............................................
  194.     -- .                                            .
  195.     -- . FILE_NAME                                  . BODY
  196.     -- .                                            .
  197.     -- ..............................................
  198.     function FILE_NAME return STRING is
  199.         TEMP : FNAME_POINTER;
  200.     begin
  201.         if not INIT_DONE then
  202.             raise INIT_ERROR;
  203.         else
  204.           if IS_END then
  205.               raise END_OF_FILE_LIST;
  206.           end if;
  207.           TEMP         := CURRENT_FILE;
  208.           CURRENT_FILE := CURRENT_FILE.NEXT;
  209.           return TEMP.NAME;
  210.         end if;
  211.     exception
  212.         when INIT_ERROR       => raise;
  213.         when END_OF_FILE_LIST => raise;
  214.         when others           => raise UNEXPECTED_ERROR;
  215.     end FILE_NAME;
  216.  
  217.     -- ..............................................
  218.     -- .                                            .
  219.     -- . OUTPUT_FILE_NAME                           . BODY
  220.     -- .                                            .
  221.     -- ..............................................
  222.     function OUTPUT_FILE_NAME return STRING is
  223.     begin
  224.         if not INIT_DONE then
  225.             raise INIT_ERROR;
  226.         else
  227.             if OUTPUT_FILE_EXISTS then
  228.                 return CLI.ARGV(NUMBER_OF_FILE_NAME_TOKENS);
  229.             else
  230.                 return "";
  231.             end if;
  232.         end if;
  233.     exception
  234.         when INIT_ERROR => raise;
  235.         when others     => raise UNEXPECTED_ERROR;
  236.     end OUTPUT_FILE_NAME;
  237.  
  238.     -- ..............................................
  239.     -- .                                            .
  240.     -- . FILE_NAME_COUNT                            . BODY
  241.     -- .                                            .
  242.     -- ..............................................
  243.     function FILE_NAME_COUNT return NATURAL is
  244.     begin
  245.         if not INIT_DONE then
  246.             raise INIT_ERROR;
  247.         else
  248.             return NUMBER_OF_FILE_NAME_TOKENS;
  249.         end if;
  250.     exception
  251.         when INIT_ERROR => raise;
  252.         when others     => raise UNEXPECTED_ERROR;
  253.     end FILE_NAME_COUNT;
  254.  
  255. end COMMAND_LINE_PROCESSOR;
  256. --::::::::::
  257. --cmd_body.a
  258. --::::::::::
  259. -- **********************************
  260. -- *                                *
  261. -- *  Command                       *  BODY
  262. -- *                                *
  263. -- **********************************
  264. with Console;
  265. with Contents;
  266. with Environment;
  267. with Error_Log;
  268. with Index;
  269. with Input_File;
  270. with Macro;
  271. with Parse;
  272. with Variable;
  273. with Word_Processor;
  274. package body Command is
  275.  
  276. --| Notes (none)
  277. --|
  278. --| Modifications
  279. --| 08/16/89  Rick Conn    Initial Version
  280. --| 02/26/90  Rick Conn    Add Disable Underline
  281. --| 02/26/90  Rick Conn    Add trim of tail as well as front
  282.  
  283.   Default_Bottom
  284.     : constant NATURAL
  285.       := Formatted_Output_File.Page_Attribute_Defaults
  286.         (Formatted_Output_File.Bottom_Margin);
  287.  
  288.   Default_Footer
  289.     : constant NATURAL
  290.       := Formatted_Output_File.Page_Attribute_Defaults
  291.         (Formatted_Output_File.Footer_Lines);
  292.  
  293.   Default_Header
  294.     : constant NATURAL
  295.       := Formatted_Output_File.Page_Attribute_Defaults
  296.         (Formatted_Output_File.Header_Lines);
  297.  
  298.   Default_Top
  299.     : constant NATURAL
  300.       := Formatted_Output_File.Page_Attribute_Defaults
  301.         (Formatted_Output_File.Top_Margin);
  302.  
  303.   Default_Contents_Indentation
  304.     : constant NATURAL
  305.       := 3;
  306.  
  307.   Is_Bolding
  308.     : BOOLEAN
  309.       := true;
  310.  
  311.   Is_Underlining
  312.     : BOOLEAN
  313.       := true;
  314.  
  315.   Last_Contents_Indent
  316.     : NATURAL
  317.       := 0;
  318.  
  319.   Index_File_Name
  320.     : constant STRING
  321.       := "ptf.idx";
  322.  
  323.   Index_Is_Open
  324.     : BOOLEAN
  325.       := false;
  326.  
  327.   Index_Line_Length
  328.     : NATURAL
  329.       := 35;
  330.  
  331.   package Fof
  332.     renames Formatted_Output_File;
  333.  
  334.   use Command_Symbols;                           -- for visibility of "="
  335.   use Formatted_Output_File;
  336.   use Macro;
  337.   use Word_Processor;
  338.  
  339.   -- ..................................
  340.   -- .                                .
  341.   -- .  Convert                       .  SPEC & BODY
  342.   -- .                                .
  343.   -- ..................................
  344.   function Convert
  345.     ( Item           : in STRING )
  346.       return Command_Text is
  347.  
  348.   --| Purpose
  349.   --| Convert converts the passed string into a string of type
  350.   --| COMMAND_TEXT.  If the passed string is longer than COMMAND_TEXT,
  351.   --| it is truncated;
  352.   --|
  353.   --| Exceptions (none)
  354.   --| Notes (none)
  355.  
  356.     Result
  357.       : Command_Text
  358.         := (others         => ' ');
  359.  
  360.     Item_Start
  361.       : NATURAL
  362.         := Item'First;
  363.  
  364.     Item_End
  365.       : NATURAL
  366.         := Item'First + Command_Text'Length - 1;
  367.  
  368.   begin -- Convert
  369.  
  370.     if Item'Length <= Command_Text'Length then
  371.       Result(1 .. Item'Length) := Item;
  372.     else
  373.       Result         := Item(Item_Start .. Item_End);
  374.     end if;
  375.     return Result;
  376.  
  377.   end Convert;
  378.  
  379.   -- ..................................
  380.   -- .                                .
  381.   -- .  Spaces                        .  SPEC & BODY
  382.   -- .                                .
  383.   -- ..................................
  384.   function Spaces
  385.     ( Number         : in NATURAL )
  386.       return STRING is
  387.  
  388.   --| Purpose
  389.   --| Spaces generates a string of the indicated number of spaces.
  390.   --|
  391.   --| Exceptions (none)
  392.   --| Notes (none)
  393.  
  394.     Result
  395.       : STRING (1 .. Number + 1)
  396.         := (others         => ' ');
  397.  
  398.   begin -- Spaces
  399.  
  400.     return Result(1 .. Number);
  401.  
  402.   end Spaces;
  403.  
  404.   -- ..................................
  405.   -- .                                .
  406.   -- .  To_Nat                        .  SPEC & BODY
  407.   -- .                                .
  408.   -- ..................................
  409.   function To_Nat
  410.     ( Number         : in STRING )
  411.       return NATURAL is
  412.  
  413.   --| Purpose
  414.   --| To_Nat converts a string of digits to a natural number with
  415.   --| error checking.
  416.   --|
  417.   --| Exceptions (none)
  418.   --| Notes (none)
  419.  
  420.     Result
  421.       : NATURAL;
  422.  
  423.   begin -- To_Nat
  424.  
  425.     Result         := NATURAL'Value(Number);
  426.     return Result;
  427.   exception -- To_Nat -- To_Nat
  428.     when others =>
  429.       Error_Log.Write_Error(Error_Number & """" & Number & """");
  430.       return 0;
  431.  
  432.   end To_Nat;
  433.  
  434.   -- ..................................
  435.   -- .                                .
  436.   -- .  Adjust                        .  SPEC & BODY
  437.   -- .                                .
  438.   -- ..................................
  439.   function Adjust
  440.     ( Original_Value : in NATURAL;
  441.       Text           : in STRING )
  442.       return NATURAL is
  443.  
  444.   --| Purpose
  445.   --| Adjust accepts strings of the form "n", "+n", and "-n",
  446.   --| converts the "n" to a natural number, and, if "+n" or "-n",
  447.   --| adjusts the Original_Value by that amount.  If "n", it ignores
  448.   --| the Original_Value and just returns that amount.
  449.   --|
  450.   --| Exceptions (none)
  451.   --| Notes (none)
  452.  
  453.     Result
  454.       : NATURAL
  455.         := Original_Value;
  456.  
  457.     Temp
  458.       : NATURAL;
  459.  
  460.     type OPERATION is
  461.       ( INCREMENT, DECREMENT, SET );
  462.  
  463.     Op
  464.       : OPERATION;
  465.  
  466.     Scan_Start
  467.       : NATURAL;
  468.  
  469.     Scan_End
  470.       : NATURAL;
  471.  
  472.   begin -- Adjust
  473.  
  474.     if Text'Length > 0 then
  475.       case Text(Text'First) is
  476.         when '+' =>
  477.           Op             := INCREMENT;
  478.           Scan_Start     := Text'First + 1;
  479.         when '-' =>
  480.           Op             := DECREMENT;
  481.           Scan_Start     := Text'First + 1;
  482.         when others =>
  483.           Op             := SET;
  484.           Scan_Start     := Text'First;
  485.       end case;
  486.       Scan_End       := Text'Last;
  487.       for I in Scan_Start .. Text'Last loop
  488.         if Text(I) <= ' ' then
  489.           Scan_End       := I - 1;
  490.           exit;
  491.         end if;
  492.       end loop;
  493.  
  494.       Temp           := To_Nat(Text(Scan_Start .. Scan_End));
  495.  
  496.       case Op is
  497.         when INCREMENT =>
  498.           Result         := Original_Value + Temp;
  499.         when DECREMENT =>
  500.           if Original_Value >= Temp then
  501.             Result         := Original_Value - Temp;
  502.           else
  503.             Result         := 0;
  504.           end if;
  505.         when SET =>
  506.           Result         := Temp;
  507.       end case;
  508.  
  509.     end if;
  510.  
  511.     return Result;
  512.  
  513.   end Adjust;
  514.  
  515.   -- ..................................
  516.   -- .                                .
  517.   -- .  Identify                      .  BODY
  518.   -- .                                .
  519.   -- ..................................
  520.   function Identify
  521.     ( Item           : in STRING )
  522.       return Command_Id is
  523.  
  524.   --| Notes (none)
  525.  
  526.     Target_Command
  527.       : Command_Text
  528.         := Convert(Item);
  529.  
  530.     Result
  531.       : Command_Id
  532.         := Unknown;
  533.  
  534.   begin -- Identify
  535.  
  536.     for I in Cl'range loop
  537.       if Target_Command = Cl(I).Name then
  538.         Result         := Cl(I).Id;
  539.         exit;
  540.       end if;
  541.     end loop;
  542.     return Result;
  543.  
  544.   exception
  545.     when others =>
  546.       Error_Log.Write_Error(Error_Internal_Identify);
  547.       return Unknown;
  548.  
  549.   end Identify;
  550.  
  551.   -- ..................................
  552.   -- .                                .
  553.   -- .  Process                       .  BODY
  554.   -- .                                .
  555.   -- ..................................
  556.   procedure Process
  557.     ( Id             : in Command_Id;
  558.       Line_Tail      : in STRING;
  559.       Target         : in out Formatted_Output_File.File;
  560.       Input_File_Id  : in out Input_File.File_Type ) is
  561.  
  562.   --| Notes (none)
  563.  
  564.     Temp
  565.       : NATURAL;
  566.  
  567.     Temp1
  568.       : NATURAL;
  569.  
  570.     Old_Value
  571.       : NATURAL;
  572.  
  573.     Line_To_Write
  574.       : STRING (1 .. Ltw_Length);
  575.  
  576.     Ltw_Last
  577.       : NATURAL;
  578.  
  579.     Mid
  580.       : Macro.Macro_Id;
  581.  
  582.     Mid_Read
  583.       : Macro.Macro_Id;
  584.  
  585.     Mstatus
  586.       : Macro.Macro_Status;
  587.  
  588.     Inline
  589.       : STRING (1 .. 200);
  590.  
  591.     Inlast
  592.       : NATURAL;
  593.  
  594.     Inline_Verb
  595.       : STRING (1 .. 200);
  596.  
  597.     Inlast_Verb
  598.       : NATURAL;
  599.  
  600.     Inline_Tail
  601.       : STRING (1 .. 200);
  602.  
  603.     Inlast_Tail
  604.       : NATURAL;
  605.  
  606.     Hf_Left
  607.       : STRING (1 .. 100);
  608.  
  609.     Hf_Llast
  610.       : NATURAL;
  611.  
  612.     Hf_Center
  613.       : STRING (1 .. 100);
  614.  
  615.     Hf_Clast
  616.       : NATURAL;
  617.  
  618.     Hf_Right
  619.       : STRING (1 .. 100);
  620.  
  621.     Hf_Rlast
  622.       : NATURAL;
  623.  
  624.     Hf_Line
  625.       : Fof.Header_Footer_Line;
  626.  
  627.     type HF_TYPE is
  628.       ( FOOTER_LINE, HEADER_LINE );
  629.  
  630.     Command_Name
  631.       : Command_Symbols.Command_Text;
  632.  
  633.       -- ..................................
  634.       -- .                                .
  635.       -- .  Process.Parse_Hf              .  SPEC & BODY
  636.       -- .                                .
  637.       -- ..................................
  638.  
  639.     function Parse_Hf
  640.       ( Line           : in STRING;
  641.         Kind           : in HF_TYPE )
  642.         return Fof.Header_Footer_Line is
  643.  
  644.     --| Purpose
  645.     --| Parse_Hf accepts a Line of the form /--/--/--/ or #/--/--/--/
  646.     --| and places the three parts into Hf_Left, Hf_Center, and Hf_Right.
  647.     --| If the # is present, it returns the #; else, it returns the default
  648.     --| value for the # based on Kind.
  649.     --|
  650.     --| Exceptions (none)
  651.     --| Notes (none)
  652.  
  653.       Default_Header_Line
  654.         : Fof.Header_Footer_Line
  655.           := 1;
  656.  
  657.       Default_Footer_Line
  658.         : Fof.Header_Footer_Line
  659.           := 2;
  660.  
  661.       Hf_Line_Number
  662.         : Fof.Header_Footer_Line;
  663.  
  664.       Temp
  665.         : NATURAL;
  666.  
  667.       Fof_Kind
  668.         : Fof.Page_Attribute;
  669.  
  670.       Start
  671.         : NATURAL
  672.           := Line'First;
  673.  
  674.       Delimiter
  675.         : CHARACTER;
  676.  
  677.         -- ..................................
  678.         -- .                                .
  679.         -- .  Process.Parse_Hf.Sub_Parse    .  SPEC & BODY
  680.         -- .                                .
  681.         -- ..................................
  682.  
  683.       procedure Sub_Parse
  684.         ( Item           : in out STRING;
  685.           Last           : out NATURAL ) is
  686.  
  687.       --| Purpose
  688.       --| Sub_Parse parses Line starting at Start until Delimiter
  689.       --| or Line'Last is encountered.  It places the parsed-out
  690.       --| string into Item and returns the index of the last character.
  691.       --|
  692.       --| Exceptions (none)
  693.       --| Notes (none)
  694.  
  695.         Item_Index
  696.           : NATURAL
  697.             := Item'First - 1;
  698.  
  699.         Stop
  700.           : NATURAL
  701.             := Line'Last + 1;
  702.  
  703.       begin -- Sub_Parse
  704.  
  705.         if Start <= Line'Last then
  706.           for I in Start .. Line'Last loop
  707.             if Line(I) = Delimiter then
  708.               Stop           := I;
  709.               exit;
  710.             else
  711.               Item_Index     := Item_Index + 1;
  712.               Item(Item_Index) := Line(I);
  713.             end if;
  714.           end loop;
  715.           Start          := Stop + 1;
  716.         end if;
  717.         while Item_Index >= Item'First loop
  718.         -- remove trailing white space
  719.           exit when Item(Item_Index) > ' ';
  720.           Item_Index := Item_Index - 1;
  721.         end loop;
  722.         Last           := Item_Index;
  723.  
  724.       end Sub_Parse;
  725.  
  726.     begin -- Parse_Hf
  727.  
  728.       case Kind is
  729.         when HEADER_LINE =>
  730.           Hf_Line_Number := Default_Header_Line;
  731.           Fof_Kind       := Fof.Header_Lines;
  732.         when FOOTER_LINE =>
  733.           Hf_Line_Number := Default_Footer_Line;
  734.           Fof_Kind       := Fof.Footer_Lines;
  735.       end case;
  736.       if Line'Length > 0 then
  737.         if (Line(Start) >= '0') and (Line(Start) <= '9') then
  738.           Temp           := To_Nat(Line(Start .. Start));
  739.           if (Temp > 0)
  740.               and (Temp <= Fof.Get_Page_Attribute(Target, Fof_Kind)) then
  741.             Hf_Line_Number := Fof.Header_Footer_Line(Temp);
  742.           else
  743.             Error_Log.Write_Error(Error_Hf_Lines);
  744.           end if;
  745.           Start          := Start + 1;
  746.         end if;
  747.         Temp           := Start;
  748.         Start          := Line'Last + 1;
  749.         for I in Temp .. Line'Last loop
  750.           if Line(I) > ' ' then
  751.             Start          := I;
  752.             exit;
  753.           end if;
  754.         end loop;
  755.         if Start <= Line'Last then
  756.           Delimiter      := Line(Start);
  757.           Start          := Start + 1;
  758.           Sub_Parse(Hf_Left, Hf_Llast);
  759.           Sub_Parse(Hf_Center, Hf_Clast);
  760.           Sub_Parse(Hf_Right, Hf_Rlast);
  761.         end if;
  762.       else
  763.         Hf_Llast       := 0;
  764.         Hf_Clast       := 0;
  765.         Hf_Rlast       := 0;
  766.       end if;
  767.       return Hf_Line_Number;
  768.  
  769.     end Parse_Hf;
  770.  
  771.     -- ..................................
  772.     -- .                                .
  773.     -- .  Process.Interpret_Write       .  SPEC & BODY
  774.     -- .                                .
  775.     -- ..................................
  776.     procedure Interpret_Write
  777.       ( In_String      : in STRING;
  778.         Out_String     : out STRING;
  779.         Out_Last       : out NATURAL ) is
  780.  
  781.     --| Purpose
  782.     --| Interpret_Write interprets control and escape characters
  783.     --| from In_String, placing the result into Out_String.
  784.     --| Interpret_Write is only called by the WRITE command
  785.     --| processing section of code.
  786.     --|
  787.     --| Exceptions (none)
  788.     --| Notes (none)
  789.  
  790.       O_Index
  791.         : NATURAL
  792.           := Out_String'First;
  793.  
  794.       type STATE_TYPE is
  795.         ( IN_CONTROL, IN_ESCAPE, IN_TEXT );
  796.  
  797.       Current_State
  798.         : STATE_TYPE
  799.           := IN_TEXT;
  800.  
  801.     begin -- Interpret_Write
  802.  
  803.       for I in In_String'range loop
  804.         case Current_State is
  805.           when IN_TEXT =>
  806.             case In_String(I) is
  807.               when '^' =>
  808.                 Current_State  := IN_CONTROL;
  809.               when '\' =>
  810.                 Current_State  := IN_ESCAPE;
  811.               when others =>
  812.                 if O_Index <= Out_String'Last then
  813.                   Out_String(O_Index) := In_String(I);
  814.                   O_Index        := O_Index + 1;
  815.                 else
  816.                   Error_Log.Write_Error(Error_Write);
  817.                   exit;
  818.                 end if;
  819.             end case;
  820.           when IN_CONTROL =>
  821.             Temp           := CHARACTER'Pos(In_String(I))
  822.                 - CHARACTER'Pos('@');
  823.             if O_Index <= Out_String'Last then
  824.               Out_String(O_Index) := CHARACTER'Val(Temp);
  825.               O_Index        := O_Index + 1;
  826.             else
  827.               Error_Log.Write_Error(Error_Write);
  828.               exit;
  829.             end if;
  830.             Current_State  := IN_TEXT;
  831.           when IN_ESCAPE =>
  832.             if O_Index <= Out_String'Last then
  833.               case In_String(I) is
  834.                 when 'b' =>
  835.                   Out_String(O_Index) := Ascii.Bs;
  836.                 when 'd' =>
  837.                   Out_String(O_Index) := Ascii.Del;
  838.                 when 'e' =>
  839.                   Out_String(O_Index) := Ascii.Esc;
  840.                 when 'n' =>
  841.                   Out_String(O_Index) := Ascii.Lf;
  842.                 when 'r' =>
  843.                   Out_String(O_Index) := Ascii.Cr;
  844.                 when 't' =>
  845.                   Out_String(O_Index) := Ascii.Ht;
  846.                 when others =>
  847.                   Out_String(O_Index) := In_String(I);
  848.               end case;
  849.               O_Index        := O_Index + 1;
  850.             else
  851.               Error_Log.Write_Error(Error_Write);
  852.               exit;
  853.             end if;
  854.             Current_State  := IN_TEXT;
  855.         end case;
  856.       end loop;
  857.       Out_Last       := O_Index - 1;
  858.  
  859.     end Interpret_Write;
  860.  
  861.     -- ..................................
  862.     -- .                                .
  863.     -- .  Process.Check_Margins         .  SPEC & BODY
  864.     -- .                                .
  865.     -- ..................................
  866.     function Check_Margins
  867.         return BOOLEAN is
  868.  
  869.     --| Purpose
  870.     --| Check_Margins is a common routine for checking to ensure that
  871.     --| the margins are OK before a change is fully put into effect.
  872.     --| Return TRUE if margins are OK.
  873.     --|
  874.     --| Exceptions (none)
  875.     --| Notes (none)
  876.  
  877.       Result
  878.         : BOOLEAN;
  879.  
  880.     begin -- Check_Margins
  881.  
  882.       Result         := (Fof.Get_Page_Attribute(Target, Fof.Left_Margin)
  883.           + Fof.Get_Page_Attribute(Target, Fof.Left_Indent))
  884.           < (Fof.Get_Page_Attribute(Target, Fof.Right_Margin)
  885.           - Fof.Get_Page_Attribute(Target, Fof.Right_Indent));
  886.  
  887.       if not Result then
  888.         Error_Log.Write_Error(Error_Margin);
  889.       end if;
  890.  
  891.       return Result;
  892.  
  893.     end Check_Margins;
  894.  
  895.     -- ..................................
  896.     -- .                                .
  897.     -- .  Process.Add_Line_To_Macro     .  SPEC & BODY
  898.     -- .                                .
  899.     -- ..................................
  900.     function Add_Line_To_Macro
  901.         return BOOLEAN is
  902.  
  903.     --| Purpose
  904.     --| In the environment of Process, Add_Line_To_Macro adds the line
  905.     --| Inline(1..Inlast) as the next line in the macro.  If this line
  906.     --| is itself a macro, then its macro definition is added.
  907.     --|
  908.     --| Exceptions (none)
  909.     --| Notes
  910.     --|   Variables Process.Inline and Process.Inlast are accessed.
  911.     --|   Variables Process.Inline_Verb, Process.Inline_Tail,
  912.     --| Process.Inlast_Verb, and Process.Inlast_Tail are altered.
  913.  
  914.       Continue
  915.         : BOOLEAN
  916.           := true;
  917.  
  918.     begin -- Add_Line_To_Macro
  919.  
  920.       if Inline(1) = Variable.Cc then
  921.       -- Dot command
  922.  
  923.         Parse(Inline(2 .. Inlast), Inline_Verb, Inline_Tail, Inlast_Verb,
  924.             Inlast_Tail);
  925.         if Command.Identify(Inline_Verb(1 .. Inlast_Verb)) = Stop_Macro then
  926.         -- End of macro encountered
  927.  
  928.           Continue       := false;
  929.  
  930.         else
  931.         -- Inside macro
  932.  
  933.           if Command.Identify(Inline_Verb(1 .. Inlast_Verb)) = Unknown then
  934.           -- Not a normal command
  935.  
  936.             if Macro.Locate(Inline_Verb(1 .. Inlast_Verb)) = Macro.Ok then
  937.               Macro.Open(Inline_Verb(1 .. Inlast_Verb), Mid_Read, Mstatus);
  938.               while not Macro.Is_Empty(Mid_Read) loop
  939.                 Macro.Read(Mid_Read, Inline, Inlast);
  940.                 Macro.Write(Mid, Inline(1 .. Inlast));
  941.               end loop;
  942.               Macro.Close(Mid_Read);
  943.             else
  944.               Error_Log.Write_Error(Error_Macro_Unknown_Command);
  945.             end if;
  946.  
  947.           else
  948.           -- Normal command
  949.  
  950.             Macro.Write(Mid, Inline(1 .. Inlast));
  951.           end if;
  952.         end if;
  953.  
  954.       else
  955.       -- Not dot command
  956.  
  957.         Macro.Write(Mid, Inline(1 .. Inlast));
  958.  
  959.       end if;
  960.       return Continue;
  961.  
  962.     end Add_Line_To_Macro;
  963.  
  964.     -- ..................................
  965.     -- .                                .
  966.     -- .  Process.Fill_Command_Name     .  SPEC & BODY
  967.     -- .                                .
  968.     -- ..................................
  969.     procedure Fill_Command_Name
  970.       ( What           : in STRING ) is
  971.  
  972.     --| Purpose
  973.     --| Fill_Command_Name places the string in What into the variable
  974.     --| Command_Name, space-filling if necessary.
  975.     --|
  976.     --| Exceptions (none)
  977.     --| Notes
  978.     --|   Variable Process.Command_Name is altered
  979.  
  980.       Last
  981.         : NATURAL;
  982.  
  983.       Index
  984.         : NATURAL
  985.           := Command_Name'First;
  986.  
  987.     begin -- Fill_Command_Name
  988.  
  989.       Command_Name   := (others         => ' ');
  990.       if What'Length <= Command_Name'Length then
  991.         Last           := What'Last;
  992.       else
  993.         Last           := What'First + Command_Name'Length - 1;
  994.       end if;
  995.       for I in What'First .. Last loop
  996.         Command_Name(Index) := What(I);
  997.         Index          := Index + 1;
  998.       end loop;
  999.  
  1000.     end Fill_Command_Name;
  1001.  
  1002.   begin -- Process
  1003.  
  1004.     case Id is
  1005.  
  1006.       when Auto_Paragraph =>
  1007.         Variable.Set_Auto_Paragraph(true);
  1008.  
  1009.       when Bold =>
  1010.         if Is_Bolding then
  1011.           if Line_Tail'Length > 0 then
  1012.             if Line_Tail(1) = 'o' then
  1013.               if Line_Tail(2) = 'n' then
  1014.                 Fof.Set_Line_Attribute(Target, Fof.Bold, Fof.On);
  1015.               else
  1016.                 Fof.Set_Line_Attribute(Target, Fof.Bold, Fof.Off);
  1017.               end if;
  1018.             else
  1019.               Temp           := To_Nat(Line_Tail);
  1020.               if Temp > 0 then
  1021.                 Variable.Set_Bold_Count(Temp);
  1022.                 Fof.Set_Line_Attribute(Target, Fof.Bold, Fof.On);
  1023.               end if;
  1024.             end if;
  1025.           else
  1026.             Variable.Set_Bold_Count(1);
  1027.             Fof.Set_Line_Attribute(Target, Fof.Bold, Fof.On);
  1028.           end if;
  1029.         end if;
  1030.  
  1031.       when Break =>
  1032.         Fof.Break_Line(Target);
  1033.  
  1034.       when Center =>
  1035.         Fof.Break_Line(Target);
  1036.         if Line_Tail'Length > 0 then
  1037.           if Line_Tail(1) = 'o' then
  1038.             if Line_Tail(2) = 'n' then
  1039.               Fof.Set_Line_Attribute(Target, Fof.Center, Fof.On);
  1040.             else
  1041.               Fof.Set_Line_Attribute(Target, Fof.Center, Fof.Off);
  1042.             end if;
  1043.           else
  1044.             Temp           := To_Nat(Line_Tail);
  1045.             if Temp > 0 then
  1046.               Variable.Set_Center_Count(Temp);
  1047.               Fof.Set_Line_Attribute(Target, Fof.Center, Fof.On);
  1048.             else
  1049.               Fof.Set_Line_Attribute(Target, Fof.Center, Fof.Off);
  1050.             end if;
  1051.           end if;
  1052.         else
  1053.           Variable.Set_Center_Count(1);
  1054.           Fof.Set_Line_Attribute(Target, Fof.Center, Fof.On);
  1055.         end if;
  1056.  
  1057.       when Comment =>
  1058.         null;
  1059.  
  1060.       when Console_Message =>
  1061.         Console.Put_Line(Line_Tail);
  1062.  
  1063.       when Contents_Select =>
  1064.         if Line_Tail'Length > 0 then
  1065.           Temp := To_Nat(Line_Tail);
  1066.           if Temp <= 5 then
  1067.             Contents.Select_Table(Temp);
  1068.           else
  1069.             Error_Log.Write_Warning(Warning_Contents_Number);
  1070.             Contents.Select_Table(0);
  1071.           end if;
  1072.         else
  1073.           Contents.Select_Table(0);
  1074.         end if;
  1075.  
  1076.       when Disable_Bolding =>
  1077.         Is_Bolding     := false;
  1078.  
  1079.       when Enable_Bolding =>
  1080.         Is_Bolding     := true;
  1081.  
  1082.       when Enter_Contents =>
  1083.         Fof.Break_Line(Target);
  1084.         if Line_Tail'Length > 0 then
  1085.           if Line_Tail(1) in '0' .. '9' then
  1086.             Parse(Line_Tail, Inline_Verb, Inline_Tail, Inlast_Verb,
  1087.                 Inlast_Tail);
  1088.             Last_Contents_Indent := To_Nat(Inline_Verb(1 .. Inlast_Verb));
  1089.             Contents.Add_Line(Last_Contents_Indent,
  1090.                 Inline_Tail(1 .. Inlast_Tail), Fof.Current_Page(Target));
  1091.           else
  1092.             Contents.Add_Line(Last_Contents_Indent, Line_Tail,
  1093.                 Fof.Current_Page(Target));
  1094.           end if;
  1095.         else
  1096.           Contents.Add_Line(0, "", Fof.Current_Page(Target));
  1097.         end if;
  1098.  
  1099.       when Environment_Pop =>
  1100.         Fof.Break_Line(Target);
  1101.         Environment.Pop(Target, Is_Bolding, Is_Underlining);
  1102.  
  1103.       when Environment_Push =>
  1104.         Fof.Break_Line(Target);
  1105.         Environment.Push(Target, Is_Bolding, Is_Underlining);
  1106.  
  1107.       when Fill =>
  1108.         Fof.Break_Line(Target);
  1109.         Fof.Set_Line_Attribute(Target, Fof.Fill, Fof.On);
  1110.  
  1111.       when Footer =>
  1112.         Hf_Line        := Parse_Hf(Line_Tail, FOOTER_LINE);
  1113.         if Hf_Line > 0 then
  1114.           Fof.Set_Footer_Line(Target, Fof.All_Pages, Hf_Line, Hf_Left(1 ..
  1115.               Hf_Llast), Hf_Center(1 .. Hf_Clast), Hf_Right(1 .. Hf_Rlast));
  1116.         else
  1117.           Error_Log.Write_Error(Error_Hf_Lines);
  1118.         end if;
  1119.  
  1120.       when Footer_Even =>
  1121.         Hf_Line        := Parse_Hf(Line_Tail, FOOTER_LINE);
  1122.         if Hf_Line > 0 then
  1123.           Fof.Set_Footer_Line(Target, Fof.Even_Pages, Hf_Line, Hf_Left(1 ..
  1124.               Hf_Llast), Hf_Center(1 .. Hf_Clast), Hf_Right(1 .. Hf_Rlast));
  1125.         else
  1126.           Error_Log.Write_Error(Error_Hf_Lines);
  1127.         end if;
  1128.  
  1129.       when Footer_Odd =>
  1130.         Hf_Line        := Parse_Hf(Line_Tail, FOOTER_LINE);
  1131.         if Hf_Line > 0 then
  1132.           Fof.Set_Footer_Line(Target, Fof.Odd_Pages, Hf_Line, Hf_Left(1 ..
  1133.               Hf_Llast), Hf_Center(1 .. Hf_Clast), Hf_Right(1 .. Hf_Rlast));
  1134.         else
  1135.           Error_Log.Write_Error(Error_Hf_Lines);
  1136.         end if;
  1137.  
  1138.       when Header =>
  1139.         Hf_Line        := Parse_Hf(Line_Tail, HEADER_LINE);
  1140.         if Hf_Line > 0 then
  1141.           Fof.Set_Header_Line(Target, Fof.All_Pages, Hf_Line, Hf_Left(1 ..
  1142.               Hf_Llast), Hf_Center(1 .. Hf_Clast), Hf_Right(1 .. Hf_Rlast));
  1143.         else
  1144.           Error_Log.Write_Error(Error_Hf_Lines);
  1145.         end if;
  1146.  
  1147.       when Header_Even =>
  1148.         Hf_Line        := Parse_Hf(Line_Tail, HEADER_LINE);
  1149.         if Hf_Line > 0 then
  1150.           Fof.Set_Header_Line(Target, Fof.Even_Pages, Hf_Line, Hf_Left(1 ..
  1151.               Hf_Llast), Hf_Center(1 .. Hf_Clast), Hf_Right(1 .. Hf_Rlast));
  1152.         else
  1153.           Error_Log.Write_Error(Error_Hf_Lines);
  1154.         end if;
  1155.  
  1156.       when Header_Odd =>
  1157.         Hf_Line        := Parse_Hf(Line_Tail, HEADER_LINE);
  1158.         if Hf_Line > 0 then
  1159.           Fof.Set_Header_Line(Target, Fof.Odd_Pages, Hf_Line, Hf_Left(1 ..
  1160.               Hf_Llast), Hf_Center(1 .. Hf_Clast), Hf_Right(1 .. Hf_Rlast));
  1161.         else
  1162.           Error_Log.Write_Error(Error_Hf_Lines);
  1163.         end if;
  1164.  
  1165.       when Include =>
  1166.         if Line_Tail'Length > 0 then
  1167.           if Word_Processor.Process_Source_File(Line_Tail)
  1168.               = Word_Processor.Not_Ok then
  1169.             Error_Log.Write_Error(Error_Include & Line_Tail);
  1170.           end if;
  1171.         else
  1172.           Error_Log.Write_Error(Error_Include & Line_Tail);
  1173.         end if;
  1174.  
  1175.       when Index_Entry =>
  1176.         if Line_Tail'Length > 0 then
  1177.           if not Index_Is_Open then
  1178.             begin
  1179.               Temp := Fof.Get_Page_Attribute(Target, Fof.Right_Margin)
  1180.                   - Fof.Get_Page_Attribute(Target, Fof.Left_Margin) + 1;
  1181.               Temp1 := Fof.Get_Page_Attribute(Target, Fof.Total_Lines)
  1182.                   - (Fof.Get_Page_Attribute(Target, Fof.Header_Lines)
  1183.                   + Fof.Get_Page_Attribute(Target, Fof.Footer_Lines)
  1184.                   + Fof.Get_Page_Attribute(Target, Fof.Top_Margin)
  1185.                   + Fof.Get_Page_Attribute(Target, Fof.Bottom_Margin));
  1186.               Index.Create(Index_File_Name, Index_Line_Length, Temp, Temp1);
  1187.               Index_Is_Open := true;
  1188.             exception
  1189.               when others =>
  1190.                 Error_Log.Write_Error(Error_Index_File_Create);
  1191.             end;
  1192.           end if;
  1193.           if Index_Is_Open then
  1194.             begin
  1195.               Index.Add_Entry(Line_Tail, Fof.Current_Page(Target));
  1196.             exception
  1197.               when others =>
  1198.                 null;
  1199.             end;
  1200.           end if;
  1201.         end if;
  1202.  
  1203.       when Index_Length =>
  1204.         if Line_Tail'Length > 0 then
  1205.           Temp := To_Nat(Line_Tail);
  1206.           if Temp > 0 then
  1207.             Index_Line_Length := Temp;
  1208.           end if;
  1209.         end if;
  1210.  
  1211.       when Justify =>
  1212.         Fof.Break_Line(Target);
  1213.         Fof.Set_Line_Attribute(Target, Fof.Justify, Fof.On);
  1214.  
  1215.       when Left_Indent =>
  1216.         Fof.Break_Line(Target);
  1217.         Old_Value      := Fof.Get_Page_Attribute(Target, Fof.Left_Indent);
  1218.         Temp           := Adjust(Old_Value, Line_Tail);
  1219.         Fof.Set_Page_Attribute(Target, Fof.Left_Indent, Temp);
  1220.         if not Check_Margins then
  1221.           Fof.Set_Page_Attribute(Target, Fof.Left_Indent, Old_Value);
  1222.         end if;
  1223.  
  1224.       when Left_Margin =>
  1225.         Fof.Break_Line(Target);
  1226.         Old_Value      := Fof.Get_Page_Attribute(Target, Fof.Left_Margin);
  1227.         Temp           := Adjust(Old_Value, Line_Tail);
  1228.         if Temp = 0 then
  1229.           Temp           := 1;
  1230.         end if;
  1231.         Fof.Set_Page_Attribute(Target, Fof.Left_Margin, Temp);
  1232.         if not Check_Margins then
  1233.           Fof.Set_Page_Attribute(Target, Fof.Left_Margin, Old_Value);
  1234.         end if;
  1235.  
  1236.       when Lex =>
  1237.         if Line_Tail'Length > 0 then
  1238.           Parse(Line_Tail, Inline_Verb, Inline_Tail, Inlast_Verb,
  1239.               Inlast_Tail);
  1240.           Fill_Command_Name(Inline_Verb(1 .. Inlast_Verb));
  1241.           Temp           := Cl'Last + 1;
  1242.           for I in Cl'range loop
  1243.             if Command_Name = Cl(I).Name then
  1244.               Temp           := I;
  1245.               exit;
  1246.             end if;
  1247.           end loop;
  1248.           if Temp > Cl'Last then
  1249.             Error_Log.Write_Error(Error_Unknown);
  1250.           else
  1251.             Fill_Command_Name(Inline_Tail(1 .. Inlast_Tail));
  1252.             Cl(Temp).Name  := Command_Name;
  1253.           end if;
  1254.         else
  1255.           Error_Log.Write_Error(Error_Lex);
  1256.         end if;
  1257.  
  1258.       when Line_Spacing =>
  1259.         if Line_Tail'Length > 0 then
  1260.           Temp           := Fof.Get_Page_Attribute(Target, Fof.Line_Spacing)
  1261.               + 1;
  1262.           Temp           := Adjust(Temp, Line_Tail) - 1;
  1263.           Fof.Set_Page_Attribute(Target, Fof.Line_Spacing, Temp);
  1264.         else
  1265.           Fof.Set_Page_Attribute(Target, Fof.Line_Spacing, Fof.
  1266.               Page_Attribute_Defaults(Fof.Line_Spacing));
  1267.         end if;
  1268.  
  1269.       when Nl_Bottom =>
  1270.         if Line_Tail'Length > 0 then
  1271.           Temp           := To_Nat(Line_Tail);
  1272.           Fof.Set_Page_Attribute(Target, Fof.Bottom_Margin, Temp);
  1273.         else
  1274.           Fof.Set_Page_Attribute(Target, Fof.Bottom_Margin, Default_Bottom);
  1275.         end if;
  1276.  
  1277.       when Nl_Footer =>
  1278.         if Line_Tail'Length > 0 then
  1279.           Temp           := To_Nat(Line_Tail);
  1280.           if Temp > Fof.Maximum_Number_Of_Header_Footer_Lines then
  1281.             Error_Log.Write_Error(Error_Hf_Lines);
  1282.           else
  1283.             Fof.Set_Page_Attribute(Target, Fof.Footer_Lines, Temp);
  1284.             for I in 1 .. Fof.Header_Footer_Line(Temp) loop
  1285.               Fof.Set_Footer_Line(Target, Fof.All_Pages, I, "", "", "");
  1286.             end loop;
  1287.           end if;
  1288.         else
  1289.           Fof.Set_Page_Attribute(Target, Fof.Footer_Lines, Default_Footer);
  1290.         end if;
  1291.  
  1292.       when Nl_Header =>
  1293.         if Line_Tail'Length > 0 then
  1294.           Temp           := To_Nat(Line_Tail);
  1295.           if Temp > Fof.Maximum_Number_Of_Header_Footer_Lines then
  1296.             Error_Log.Write_Error(Error_Hf_Lines);
  1297.           else
  1298.             Fof.Set_Page_Attribute(Target, Fof.Header_Lines, Temp);
  1299.             for I in 1 .. Fof.Header_Footer_Line(Temp) loop
  1300.               Fof.Set_Header_Line(Target, Fof.All_Pages, I, "", "", "");
  1301.             end loop;
  1302.           end if;
  1303.         else
  1304.           Fof.Set_Page_Attribute(Target, Fof.Header_Lines, Default_Header);
  1305.         end if;
  1306.  
  1307.       when Nl_Top =>
  1308.         if Line_Tail'Length > 0 then
  1309.           Temp           := To_Nat(Line_Tail);
  1310.           Fof.Set_Page_Attribute(Target, Fof.Top_Margin, Temp);
  1311.         else
  1312.           Fof.Set_Page_Attribute(Target, Fof.Top_Margin, Default_Top);
  1313.         end if;
  1314.  
  1315.       when No_Auto_Paragraph =>
  1316.         Variable.Set_Auto_Paragraph(false);
  1317.  
  1318.       when No_Fill =>
  1319.         Fof.Break_Line(Target);
  1320.         Fof.Set_Line_Attribute(Target, Fof.Fill, Fof.Off);
  1321.  
  1322.       when No_Justify =>
  1323.         Fof.Break_Line(Target);
  1324.         Fof.Set_Line_Attribute(Target, Fof.Justify, Fof.Off);
  1325.  
  1326.       when No_Paging =>
  1327.         Fof.Break_Line(Target);
  1328.         Fof.Set_Line_Attribute(Target, Fof.Paging, Fof.Off);
  1329.  
  1330.       when Number_Register =>
  1331.         if Line_Tail'Length > 0 then
  1332.           Parse(Line_Tail, Inline_Verb, Inline_Tail, Inlast_Verb,
  1333.               Inlast_Tail);
  1334.           if Inlast_Verb > 0 then
  1335.             if Inline_Verb(1) in Variable.Nreg then
  1336.               Temp           := Variable.Nr(Inline_Verb(1));
  1337.               Variable.Set_Nr(Inline_Verb(1), Adjust(Temp, Inline_Tail(1 ..
  1338.                   Inlast_Tail)));
  1339.             else
  1340.               Error_Log.Write_Error(Error_Number_Register & "(reg ID)");
  1341.             end if;
  1342.           else
  1343.             Error_Log.Write_Error(Error_Number_Register & "(argument)");
  1344.           end if;
  1345.         else
  1346.           Error_Log.Write_Error(Error_Number_Register & "(after .nr)");
  1347.         end if;
  1348.  
  1349.       when Offset =>
  1350.         Fof.Break_Line(Target);
  1351.         if Line_Tail'Length > 0 then
  1352.           Temp           := Fof.Get_Page_Attribute(Target, Fof.Page_Offset);
  1353.           Temp           := Adjust(Temp, Line_Tail);
  1354.           Fof.Set_Page_Attribute(Target, Fof.Page_Offset, Temp);
  1355.         else
  1356.           Fof.Set_Page_Attribute(Target, Fof.Page_Offset, 0);
  1357.         end if;
  1358.  
  1359.       when Page =>
  1360.         if Line_Tail'Length > 0 then
  1361.           Temp           := To_Nat(Line_Tail);
  1362.           if Temp = 0 then
  1363.             Temp           := 1;
  1364.           end if;
  1365.           Fof.Break_Page(Target, Fof.Page_Number(Temp));
  1366.         else
  1367.           Fof.Break_Page(Target);
  1368.         end if;
  1369.  
  1370.       when Page_Number_Format =>
  1371.         if Line_Tail'Length > 0 then
  1372.           Parse(Line_Tail, Inline_Verb, Inline_Tail, Inlast_Verb,
  1373.               Inlast_Tail);
  1374.           case Inline_Verb(1) is
  1375.             when 'a' =>
  1376.               Fof.Set_Page_Number_Format(Target, Fof.Arabic,
  1377.                   Inline_Tail(1..Inlast_Tail));
  1378.             when 'l' =>
  1379.               Fof.Set_Page_Number_Format(Target, Fof.Lower_Roman,
  1380.                   Inline_Tail(1..Inlast_Tail));
  1381.             when 'u' =>
  1382.               Fof.Set_Page_Number_Format(Target, Fof.Upper_Roman,
  1383.                   Inline_Tail(1..Inlast_Tail));
  1384.             when others =>
  1385.               Error_Log.Write_Error(Error_Page_Number_Format);
  1386.           end case;
  1387.         else
  1388.           Fof.Set_Page_Number_Format(Target, Fof.Arabic, "");
  1389.         end if;
  1390.  
  1391.       when Page_Size =>
  1392.         if Line_Tail'Length > 0 then
  1393.           Temp           := Fof.Get_Page_Attribute(Target, Fof.Total_Lines);
  1394.           Temp           := Adjust(Temp, Line_Tail);
  1395.           Fof.Set_Page_Attribute(Target, Fof.Total_Lines, Temp);
  1396.         else
  1397.           Fof.Set_Page_Attribute(Target, Fof.Total_Lines, Fof.
  1398.               Page_Attribute_Defaults(Fof.Total_Lines));
  1399.         end if;
  1400.  
  1401.       when Paging =>
  1402.         Fof.Break_Line(Target);
  1403.         Fof.Set_Line_Attribute(Target, Fof.Paging, Fof.On);
  1404.  
  1405.       when Print_Contents =>
  1406.         Fof.Break_Line(Target);
  1407.         if Line_Tail'Length > 0 then
  1408.           Contents.Print(Target, To_Nat(Line_Tail));
  1409.         else
  1410.           Contents.Print(Target, Default_Contents_Indentation);
  1411.         end if;
  1412.  
  1413.       when Right_Indent =>
  1414.         Fof.Break_Line(Target);
  1415.         Old_Value      := Fof.Get_Page_Attribute(Target, Fof.Right_Indent);
  1416.         Temp           := Adjust(Old_Value, Line_Tail);
  1417.         Fof.Set_Page_Attribute(Target, Fof.Right_Indent, Temp);
  1418.         if not Check_Margins then
  1419.           Fof.Set_Page_Attribute(Target, Fof.Right_Indent, Old_Value);
  1420.         end if;
  1421.  
  1422.       when Right_Margin =>
  1423.         Fof.Break_Line(Target);
  1424.         Old_Value      := Fof.Get_Page_Attribute(Target, Fof.Right_Margin);
  1425.         Temp           := Adjust(Old_Value, Line_Tail);
  1426.         Fof.Set_Page_Attribute(Target, Fof.Right_Margin, Temp);
  1427.         if not Check_Margins then
  1428.           Fof.Set_Page_Attribute(Target, Fof.Right_Margin, Old_Value);
  1429.         end if;
  1430.  
  1431.       when Set_Cchar =>
  1432.         if Line_Tail'Length > 0 then
  1433.           Variable.Set_Cc(Line_Tail(Line_Tail'First));
  1434.         else
  1435.           Variable.Set_Cc(Variable.Default_Cc);
  1436.         end if;
  1437.  
  1438.       when Set_Echar =>
  1439.         if Line_Tail'Length > 0 then
  1440.           Variable.Set_Ec(Line_Tail(Line_Tail'First));
  1441.         else
  1442.           Variable.Set_Ec(Variable.Default_Ec);
  1443.         end if;
  1444.  
  1445.       when Set_Fchar =>
  1446.         if Line_Tail'Length > 0 then
  1447.           Variable.Set_Fc(Line_Tail(Line_Tail'First));
  1448.         else
  1449.           Variable.Set_Fc(Variable.Default_Fc);
  1450.         end if;
  1451.  
  1452.       when Skip =>
  1453.         Fof.Break_Line(Target);
  1454.         if Line_Tail'Length > 0 then
  1455.           Fof.Skip(Target, Fof.Line_Number(To_Nat(Line_Tail)));
  1456.         else
  1457.           Fof.Skip(Target, 1);
  1458.         end if;
  1459.  
  1460.       when Space_To =>
  1461.         Fof.Break_Line(Target);
  1462.         if Line_Tail'Length > 0 then
  1463.           case Line_Tail(1) is
  1464.             when '-' =>
  1465.               Temp           := Fof.Get_Page_Attribute(Target,
  1466.                   Fof.Total_Lines);
  1467.               Temp           := Temp - Fof.Get_Page_Attribute(Target,
  1468.                   Fof.Bottom_Margin);
  1469.               Temp           := Temp - Fof.Get_Page_Attribute(Target,
  1470.                   Fof.Footer_Lines);
  1471.               Temp           := Adjust(Temp, Line_Tail);
  1472.             when '+' =>
  1473.               Temp           := Fof.Get_Page_Attribute(Target,
  1474.                   Fof.Top_Margin) + 1;
  1475.               Temp           := Temp + Fof.Get_Page_Attribute(Target,
  1476.                   Fof.Header_Lines);
  1477.               Temp           := Adjust(Temp, Line_Tail);
  1478.             when others =>
  1479.               Temp           := To_Nat(Line_Tail);
  1480.           end case;
  1481.           if Temp < NATURAL(Fof.Current_Line(Target)) then
  1482.             Error_Log.Write_Error(Error_Spaceto);
  1483.           else
  1484.             Temp           := Temp - NATURAL(Fof.Current_Line(Target));
  1485.             if Temp > 0 then
  1486.               Old_Value      := Fof.Get_Page_Attribute(Target,
  1487.                   Fof.Line_Spacing);
  1488.               Fof.Set_Page_Attribute(Target, Fof.Line_Spacing, 0);
  1489.               Fof.Skip(Target, Fof.Line_Number(Temp));
  1490.               Fof.Set_Page_Attribute(Target, Fof.Line_Spacing, Old_Value);
  1491.             end if;
  1492.           end if;
  1493.         end if;
  1494.  
  1495.       when Start_Macro =>
  1496.         if Line_Tail'Length > 0 then
  1497.           Macro.Create(Line_Tail, Mid, Mstatus);
  1498.           if Mstatus = Macro.Ok then
  1499.             while not Input_File.End_Of_File(Input_File_Id) loop
  1500.               Input_File.Get_Line(Input_File_Id, Inline, Inlast);
  1501.               Variable.Increment_Line_Number;
  1502.               if Inlast > 0 then
  1503.                 exit when not Add_Line_To_Macro;
  1504.               end if;
  1505.             end loop;
  1506.             Macro.Close(Mid);
  1507.           else
  1508.             Error_Log.Write_Error(Error_Macro);
  1509.           end if;
  1510.         else
  1511.           Error_Log.Write_Error(Error_Macro);
  1512.         end if;
  1513.  
  1514.       when Stop_Macro =>
  1515.         Error_Log.Write_Error(Error_Macro_End);
  1516.  
  1517.       when Temporary_Indent =>
  1518.         Fof.Break_Line(Target);
  1519.         if Line_Tail'Length > 0 then
  1520.           Temp           := Fof.Get_Page_Attribute(Target, Fof.Left_Margin)
  1521.               + Fof.Get_Page_Attribute(Target, Fof.Left_Indent);
  1522.           Temp           := Adjust(Temp, Line_Tail);
  1523.           if Temp > 0 then
  1524.             Fof.Set_Page_Attribute(Target, Fof.Temp_Indent, Temp);
  1525.           else
  1526.             Error_Log.Write_Error(Error_Indent);
  1527.           end if;
  1528.         end if;
  1529.  
  1530.       when Test_Page =>
  1531.         if Line_Tail'Length > 0 then
  1532.           Temp           := To_Nat(Line_Tail);
  1533.           if Temp > 0 then
  1534.             if not Fof.Test_Page(Target, Fof.Line_Number(Temp)) then
  1535.               Fof.Break_Page(Target);
  1536.             end if;
  1537.           end if;
  1538.         end if;
  1539.  
  1540.       when Underline =>
  1541.         if Is_Underlining then
  1542.           if Line_Tail'Length > 0 then
  1543.             if Line_Tail(1) = 'o' then
  1544.               if Line_Tail(2) = 'n' then
  1545.                 Fof.Set_Line_Attribute(Target, Fof.Underline, Fof.On);
  1546.               else
  1547.                 Fof.Set_Line_Attribute(Target, Fof.Underline, Fof.Off);
  1548.               end if;
  1549.             else
  1550.               Temp           := To_Nat(Line_Tail);
  1551.               if Temp > 0 then
  1552.                 Variable.Set_Underline_Count(Temp);
  1553.                 Fof.Set_Line_Attribute(Target, Fof.Underline, Fof.On);
  1554.               end if;
  1555.             end if;
  1556.           else
  1557.             Variable.Set_Underline_Count(1);
  1558.             Fof.Set_Line_Attribute(Target, Fof.Underline, Fof.On);
  1559.           end if;
  1560.         end if;
  1561.  
  1562.       when Underline_Mode =>
  1563.         if Line_Tail'Length > 0 then
  1564.           case Line_Tail(1) is
  1565.             when 'a' =>
  1566.               Fof.Set_Line_Attribute(Target, Fof.Underline_Punct, Fof.On);
  1567.             when others =>
  1568.               Fof.Set_Line_Attribute(Target, Fof.Underline_Punct, Fof.Off);
  1569.           end case;
  1570.         else
  1571.           Fof.Set_Line_Attribute(Target, Fof.Underline_Punct, Fof.Off);
  1572.         end if;
  1573.  
  1574.       when Disable_Underlining =>
  1575.         Is_Underlining     := false;
  1576.  
  1577.       when Enable_Underlining =>
  1578.         Is_Underlining     := true;
  1579.  
  1580.       when Variable_Get =>
  1581.         if Line_Tail'Length > 0 then
  1582.           Parse(Line_Tail, Inline_Verb, Inline_Tail, Inlast_Verb,
  1583.               Inlast_Tail);
  1584.           if Inlast_Tail > 0 then
  1585.             Console.Put(Inline_Tail(1 .. Inlast_Tail));
  1586.           else
  1587.             Console.Put(Inline_Verb(1 .. Inlast_Verb) & "> ");
  1588.           end if;
  1589.           Console.Get_Line(Inline_Tail, Inlast_Tail);
  1590.           Variable.Set_Var(Inline_Verb(1 .. Inlast_Verb), Inline_Tail(1 ..
  1591.               Inlast_Tail));
  1592.         else
  1593.           Error_Log.Write_Error(Error_Variable_Set);
  1594.         end if;
  1595.  
  1596.       when Variable_Set =>
  1597.         if Line_Tail'Length > 0 then
  1598.           Parse(Line_Tail, Inline_Verb, Inline_Tail, Inlast_Verb,
  1599.               Inlast_Tail);
  1600.           Variable.Set_Var(Inline_Verb(1 .. Inlast_Verb), Inline_Tail(1 ..
  1601.               Inlast_Tail));
  1602.         else
  1603.           Error_Log.Write_Error(Error_Variable_Set);
  1604.         end if;
  1605.  
  1606.       when Write =>
  1607.         if Line_Tail'Length > 0 then
  1608.           Interpret_Write(Line_Tail, Line_To_Write, Ltw_Last);
  1609.           Fof.Put_Invisible_Word(Target, Line_To_Write(1 .. Ltw_Last));
  1610.         end if;
  1611.  
  1612.       when Unknown =>
  1613.         Error_Log.Write_Error(Error_Unknown);
  1614.  
  1615.     end case;
  1616.  
  1617.   exception
  1618.     when others =>
  1619.       Error_Log.Write_Error(Error_Internal_Process);
  1620.  
  1621.   end Process;
  1622.  
  1623.   -- ..................................
  1624.   -- .                                .
  1625.   -- .  Disable_Bolding               .  BODY
  1626.   -- .                                .
  1627.   -- ..................................
  1628.   procedure Disable_Bolding is
  1629.  
  1630.   --| Notes (none)
  1631.  
  1632.   begin -- Disable_Bolding
  1633.  
  1634.     Is_Bolding := false;
  1635.  
  1636.   end Disable_Bolding;
  1637.  
  1638.   -- ..................................
  1639.   -- .                                .
  1640.   -- .  Disable_Underlining           .  BODY
  1641.   -- .                                .
  1642.   -- ..................................
  1643.   procedure Disable_Underlining is
  1644.  
  1645.   --| Notes (none)
  1646.  
  1647.   begin -- Disable_Underlining
  1648.  
  1649.     Is_Underlining := false;
  1650.  
  1651.   end Disable_Underlining;
  1652.  
  1653. end Command;
  1654. --::::::::::
  1655. --cnt_body.a
  1656. --::::::::::
  1657. -- **********************************
  1658. -- *                                *
  1659. -- *  Contents                      *  BODY
  1660. -- *                                *
  1661. -- **********************************
  1662. with Command_Symbols;
  1663. with Error_Log;
  1664. with Input_File;
  1665. with Output_File;
  1666. package body Contents is
  1667.  
  1668. --| Notes (none)
  1669. --|
  1670. --| Modifications
  1671. --| 08/16/89  Rick Conn    Initial Version
  1672.  
  1673.   Current_Table
  1674.     : Table_Number
  1675.       := 0;
  1676.  
  1677.   Current_Table_File
  1678.     : STRING (1 .. 8)
  1679.       := "cnt0.cnt";
  1680.  
  1681.   Current_Number_Position
  1682.     : constant
  1683.       := 4;
  1684.  
  1685.   type TABLE_TYPE is
  1686.     record
  1687.       File_Id        : Output_File.File_Type;
  1688.       Is_Open        : BOOLEAN      := false;
  1689.     end record;
  1690.  
  1691.   type TABLE_ARRAY is
  1692.     array (Table_Number)
  1693.       of TABLE_TYPE;
  1694.  
  1695.   Table
  1696.     : TABLE_ARRAY;
  1697.  
  1698.   package Fof
  1699.     renames Formatted_Output_File;
  1700.  
  1701.   use Command_Symbols;
  1702.  
  1703.   -- ..................................
  1704.   -- .                                .
  1705.   -- .  Select_Table                  .  BODY
  1706.   -- .                                .
  1707.   -- ..................................
  1708.   procedure Select_Table
  1709.     ( Which_Table    : in Table_Number ) is
  1710.  
  1711.   --| Notes (none)
  1712.  
  1713.   begin -- Select_Table
  1714.  
  1715.     Current_Table  := Which_Table;
  1716.     Current_Table_File(Current_Number_Position)
  1717.         := CHARACTER'Val(Current_Table + CHARACTER'Pos('0'));
  1718.  
  1719.   end Select_Table;
  1720.  
  1721.   -- ..................................
  1722.   -- .                                .
  1723.   -- .  Add_Line                      .  BODY
  1724.   -- .                                .
  1725.   -- ..................................
  1726.  
  1727.   procedure Add_Line
  1728.     ( Level          : in NATURAL;
  1729.       Line           : in STRING;
  1730.       Page_Number    : in STRING ) is
  1731.  
  1732.   --| Notes (none)
  1733.  
  1734.   begin -- Add_Line
  1735.  
  1736.     if not Table(Current_Table).Is_Open then
  1737.       Output_File.Create(Table(Current_Table).File_Id, Current_Table_File);
  1738.       Table(Current_Table).Is_Open := true;
  1739.     end if;
  1740.  
  1741.     Output_File.Put_Line(Table(Current_Table).File_Id, NATURAL'Image(Level));
  1742.     Output_File.Put_Line(Table(Current_Table).File_Id, Line);
  1743.     Output_File.Put_Line(Table(Current_Table).File_Id, Page_Number);
  1744.  
  1745.   exception -- Add_Line -- Add_Line
  1746.     when others =>
  1747.       Error_Log.Write_Error(Error_Internal_Add_Line);
  1748.  
  1749.   end Add_Line;
  1750.  
  1751.   -- ..................................
  1752.   -- .                                .
  1753.   -- .  Print                         .  BODY
  1754.   -- .                                .
  1755.   -- ..................................
  1756.   procedure Print
  1757.     ( Target         : in Formatted_Output_File.File;
  1758.       Spaces_Per_Level : in NATURAL ) is
  1759.  
  1760.   --| Notes (none)
  1761.  
  1762.     Old_Fill
  1763.       : Fof.Off_On;
  1764.  
  1765.     Cline
  1766.       : STRING (1 .. 200);
  1767.  
  1768.     Cline_Last
  1769.       : NATURAL;
  1770.  
  1771.     Line
  1772.       : STRING (1 .. 200);
  1773.  
  1774.     Line_Last
  1775.       : NATURAL;
  1776.  
  1777.     Clevel
  1778.       : NATURAL;
  1779.  
  1780.     Cpage
  1781.       : STRING (1 .. 200);
  1782.  
  1783.     Cpage_Last
  1784.       : NATURAL;
  1785.  
  1786.     Start
  1787.       : NATURAL;
  1788.  
  1789.     Dummy
  1790.       : BOOLEAN;
  1791.  
  1792.     Input_File_Id
  1793.       : Input_File.File_Type;
  1794.  
  1795.       -- ..................................
  1796.       -- .                                .
  1797.       -- .  Print.Build_Line              .  SPEC & BODY
  1798.       -- .                                .
  1799.       -- ..................................
  1800.  
  1801.     procedure Build_Line
  1802.       ( Level          : in NATURAL;
  1803.         Line           : in STRING;
  1804.         Page_Number    : in STRING ) is
  1805.  
  1806.     --| Purpose
  1807.     --| Build_Line builds the table of contents line into the Cline string,
  1808.     --| setting Cline_Last to the index of the last character.
  1809.     --|
  1810.     --| Exceptions (none)
  1811.     --| Notes (none)
  1812.  
  1813.       Left
  1814.         : NATURAL
  1815.           := Spaces_Per_Level * Level + 1;
  1816.  
  1817.       Right
  1818.         : NATURAL
  1819.           := Fof.Get_Page_Attribute(Target, Fof.Right_Margin)
  1820.             - Fof.Get_Page_Attribute(Target, Fof.Page_Offset)
  1821.             - Fof.Get_Page_Attribute(Target, Fof.Left_Margin) + 1;
  1822.  
  1823.       Start
  1824.         : NATURAL
  1825.           := Left + Line'Length;
  1826.  
  1827.     begin -- Build_Line
  1828.  
  1829.       if Line'Length > 0 then
  1830.         Cline_Last     := Left - 1;
  1831.         Cline(1 .. Right) := (others         => ' ');
  1832.         Cline(Cline_Last + 1 .. Cline_Last + Line'Length) := Line;
  1833.         if Cline_Last + Line'Length > Right - Page_Number'Length then
  1834.           Error_Log.Write_Warning(Warning_Contents_Line_Truncation);
  1835.         end if;
  1836.         if (Start / 2) * 2 /= Start then
  1837.           Start          := Start + 1;
  1838.         end if;
  1839.         Start          := Start + 1;
  1840.         for I in Start .. Right loop
  1841.           Cline(I)       := '.';
  1842.         end loop;
  1843.         Cline(Right - Page_Number'Length .. Right) := " " & Page_Number;
  1844.         Cline_Last     := Right;
  1845.       else
  1846.         Cline_Last     := 0;
  1847.       end if;
  1848.  
  1849.     end Build_Line;
  1850.  
  1851.   begin -- Print
  1852.  
  1853.     Fof.Break_Line(Target);
  1854.     Old_Fill       := Fof.Get_Line_Attribute(Target, Fof.Fill);
  1855.     Fof.Set_Line_Attribute(Target, Fof.Fill, Fof.Off);
  1856.     if Table(Current_Table).Is_Open then
  1857.       Output_File.Close(Table(Current_Table).File_Id);
  1858.       Table(Current_Table).Is_Open := false;
  1859.       Input_File.Open(Input_File_Id, Current_Table_File);
  1860.       while not Input_File.End_Of_File(Input_File_Id) loop
  1861.         Input_File.Get_Line(Input_File_Id, Cline, Cline_Last);
  1862.         Start          := Cline_Last + 1;
  1863.         for I in 1 .. Cline_Last loop
  1864.           if Cline(I) > ' ' then
  1865.             Start          := I;
  1866.             exit;
  1867.           end if;
  1868.         end loop;
  1869.         if Start <= Cline_Last then
  1870.           begin
  1871.             Clevel         := NATURAL'Value(Cline(Start .. Cline_Last));
  1872.           exception
  1873.             when others =>
  1874.               Clevel         := 0;
  1875.           end;
  1876.         else
  1877.           Clevel         := 0;
  1878.         end if;
  1879.         Input_File.Get_Line(Input_File_Id, Line, Line_Last);
  1880.         Input_File.Get_Line(Input_File_Id, Cpage, Cpage_Last);
  1881.         Build_Line(Clevel, Line(1 .. Line_Last), Cpage(1 .. Cpage_Last));
  1882.         Fof.Put_Line(Target, Cline(1 .. Cline_Last));
  1883.       end loop;
  1884.       Input_File.Close(Input_File_Id);
  1885.       Dummy          := Output_File.Delete(Current_Table_File);
  1886.     else
  1887.       Error_Log.Write_Warning(Warning_Table_Empty);
  1888.     end if;
  1889.     Fof.Set_Line_Attribute(Target, Fof.Fill, Old_Fill);
  1890.  
  1891.   exception -- Print
  1892.     when others =>
  1893.       Error_Log.Write_Error(Error_Internal_Print);
  1894.  
  1895.   end Print;
  1896.  
  1897. end Contents;
  1898. --::::::::::
  1899. --cot_body.a
  1900. --::::::::::
  1901. -- **********************************
  1902. -- *                                *
  1903. -- *  Console                       *  BODY
  1904. -- *                                *
  1905. -- **********************************
  1906. with Text_IO;
  1907. package body Console is
  1908.  
  1909. --| Notes (none)
  1910. --|
  1911. --| Modifications
  1912. --| 08/16/89  Rick Conn    Initial Version
  1913.  
  1914.   -- ..................................
  1915.   -- .                                .
  1916.   -- .  Put                           .  BODY
  1917.   -- .                                .
  1918.   -- ..................................
  1919.   procedure Put
  1920.     ( Item           : in CHARACTER ) is
  1921.  
  1922.   --| Notes (none)
  1923.  
  1924.   begin -- Put
  1925.  
  1926.     Text_IO.Put(Item);
  1927.  
  1928.   end Put;
  1929.  
  1930.   -- ..................................
  1931.   -- .                                .
  1932.   -- .  Put                           .  BODY
  1933.   -- .                                .
  1934.   -- ..................................
  1935.   procedure Put
  1936.     ( Item           : in STRING ) is
  1937.  
  1938.   --| Notes (none)
  1939.  
  1940.   begin -- Put
  1941.  
  1942.     Text_IO.Put(Item);
  1943.  
  1944.   end Put;
  1945.  
  1946.   -- ..................................
  1947.   -- .                                .
  1948.   -- .  Put_Line                      .  BODY
  1949.   -- .                                .
  1950.   -- ..................................
  1951.   procedure Put_Line
  1952.     ( Item           : in STRING ) is
  1953.  
  1954.   --| Notes (none)
  1955.  
  1956.   begin -- Put_Line
  1957.  
  1958.     Text_IO.Put_Line(Item);
  1959.  
  1960.   end Put_Line;
  1961.  
  1962.   -- ..................................
  1963.   -- .                                .
  1964.   -- .  New_Line                      .  BODY
  1965.   -- .                                .
  1966.   -- ..................................
  1967.   procedure New_Line is
  1968.  
  1969.   --| Notes (none)
  1970.  
  1971.   begin -- New_Line
  1972.  
  1973.     Text_IO.New_Line;
  1974.  
  1975.   end New_Line;
  1976.  
  1977.   -- ..................................
  1978.   -- .                                .
  1979.   -- .  Get_Line                      .  BODY
  1980.   -- .                                .
  1981.   -- ..................................
  1982.   procedure Get_Line
  1983.     ( Item           : out STRING;
  1984.       Last           : out NATURAL ) is
  1985.  
  1986.   --| Notes (none)
  1987.  
  1988.   begin -- Get_Line
  1989.  
  1990.     Text_IO.Get_Line(Item, Last);
  1991.  
  1992.   end Get_Line;
  1993.  
  1994. end Console;
  1995. --::::::::::
  1996. --env_body.a
  1997. --::::::::::
  1998. -- **********************************
  1999. -- *                                *
  2000. -- *  Environment                   *  BODY
  2001. -- *                                *
  2002. -- **********************************
  2003. with Command_Symbols;
  2004. with Error_Log;
  2005. with Variable;
  2006. package body Environment is
  2007.  
  2008. --| Notes (none)
  2009. --|
  2010. --| Modifications
  2011. --| 08/16/89  Rick Conn    Initial Version
  2012. --| 02/26/90  Rick Conn    Add Set_Underlining to Pop/Push
  2013.  
  2014.   Number_Of_Stack_Elements
  2015.     : NATURAL
  2016.       := 0;
  2017.  
  2018.   type PAGE_LIST is
  2019.     array (Formatted_Output_File.Page_Attribute)
  2020.       of NATURAL;
  2021.  
  2022.   type LINE_LIST is
  2023.     array (Formatted_Output_File.Line_Attribute)
  2024.       of Formatted_Output_File.Off_On;
  2025.  
  2026.   type STACK_ELEMENT;
  2027.   type STACK_ELEMENT_POINTER is
  2028.     access STACK_ELEMENT;
  2029.  
  2030.   type STACK_ELEMENT is
  2031.     record
  2032.       Pages          : PAGE_LIST;
  2033.       Lines          : LINE_LIST;
  2034.       Cc_Val         : CHARACTER;
  2035.       Ec_Val         : CHARACTER;
  2036.       Fc_Val         : CHARACTER;
  2037.       Auto_Paragraph : BOOLEAN;
  2038.       Bolding        : BOOLEAN;
  2039.       Underlining    : BOOLEAN;
  2040.       Bold_Count     : NATURAL;
  2041.       Center_Count   : NATURAL;
  2042.       Ul_Count       : NATURAL;
  2043.       Next           : STACK_ELEMENT_POINTER := null;
  2044.       Last           : STACK_ELEMENT_POINTER := null;
  2045.     end record;
  2046.  
  2047.   Current
  2048.     : STACK_ELEMENT_POINTER
  2049.       := null;
  2050.  
  2051.   package Fof
  2052.     renames Formatted_Output_File;
  2053.  
  2054.   use Command_Symbols;
  2055.   use Formatted_Output_File;
  2056.  
  2057.   -- ..................................
  2058.   -- .                                .
  2059.   -- .  Pop                           .  BODY
  2060.   -- .                                .
  2061.   -- ..................................
  2062.   procedure Pop
  2063.     ( Item            : in Formatted_Output_File.File;
  2064.       Set_Bolding     : in out BOOLEAN;
  2065.       Set_Underlining : in out BOOLEAN ) is
  2066.  
  2067.   --| Notes (none)
  2068.  
  2069.   begin -- Pop
  2070.  
  2071.     if Number_Of_Stack_Elements = 0 then
  2072.       Error_Log.Write_Error(Error_Stack_Empty);
  2073.     else
  2074.       for I in Fof.Page_Attribute loop
  2075.         Fof.Set_Page_Attribute(Item, I, Current.Pages(I));
  2076.       end loop;
  2077.       for I in Fof.Line_Attribute loop
  2078.         if I /= Fof.Fill_State_Before_Center then
  2079.           Fof.Set_Line_Attribute(Item, I, Current.Lines(I));
  2080.         end if;
  2081.       end loop;
  2082.       Variable.Set_Cc(Current.Cc_Val);
  2083.       Variable.Set_Ec(Current.Ec_Val);
  2084.       Variable.Set_Fc(Current.Fc_Val);
  2085.       Variable.Set_Auto_Paragraph(Current.Auto_Paragraph);
  2086.       Set_Bolding := Current.Bolding;
  2087.       Set_Underlining := Current.Underlining;
  2088.       Variable.Set_Bold_Count(Current.Bold_Count);
  2089.       Variable.Set_Center_Count(Current.Center_Count);
  2090.       Variable.Set_Underline_Count(Current.Ul_Count);
  2091.       if Current.Last /= null then
  2092.         Current        := Current.Last;
  2093.       end if;
  2094.       Number_Of_Stack_Elements := Number_Of_Stack_Elements - 1;
  2095.     end if;
  2096.  
  2097.   end Pop;
  2098.  
  2099.   -- ..................................
  2100.   -- .                                .
  2101.   -- .  Push                          .  BODY
  2102.   -- .                                .
  2103.   -- ..................................
  2104.   procedure Push
  2105.     ( Item            : in Formatted_Output_File.File;
  2106.       Set_Bolding     : in BOOLEAN;
  2107.       Set_Underlining : in BOOLEAN ) is
  2108.  
  2109.   --| Notes (none)
  2110.  
  2111.     Rover
  2112.       : STACK_ELEMENT_POINTER;
  2113.  
  2114.   begin -- Push
  2115.  
  2116.     if Number_Of_Stack_Elements = 0 then
  2117.       Current        := new STACK_ELEMENT;
  2118.     else
  2119.       if Current.Next = null then
  2120.         Current.Next   := new STACK_ELEMENT;
  2121.         Rover          := Current.Next;
  2122.         Rover.Last     := Current;
  2123.       end if;
  2124.       Current        := Current.Next;
  2125.     end if;
  2126.     for I in Fof.Page_Attribute loop
  2127.       Current.Pages(I) := Fof.Get_Page_Attribute(Item, I);
  2128.     end loop;
  2129.     for I in Fof.Line_Attribute loop
  2130.       Current.Lines(I) := Fof.Get_Line_Attribute(Item, I);
  2131.     end loop;
  2132.     Current.Cc_Val := Variable.Cc;
  2133.     Current.Ec_Val := Variable.Ec;
  2134.     Current.Fc_Val := Variable.Fc;
  2135.     Current.Auto_Paragraph := Variable.Is_Auto_Paragraph;
  2136.     Current.Bolding := Set_Bolding;
  2137.     Current.Underlining := Set_Underlining;
  2138.     Current.Bold_Count := Variable.Bold_Count;
  2139.     Current.Center_Count := Variable.Center_Count;
  2140.     Current.Ul_Count := Variable.Underline_Count;
  2141.     Number_Of_Stack_Elements := Number_Of_Stack_Elements + 1;
  2142.  
  2143.   exception -- Push
  2144.     when others =>
  2145.       Error_Log.Write_Error(Error_Stack_Overflow);
  2146.  
  2147.   end Push;
  2148.  
  2149. end Environment;
  2150. --::::::::::
  2151. --err_body.a
  2152. --::::::::::
  2153. -- **********************************
  2154. -- *                                *
  2155. -- *  Error_Log                     *  BODY
  2156. -- *                                *
  2157. -- **********************************
  2158. with Console;
  2159. with Output_File;
  2160. with Variable;
  2161. package body Error_Log is
  2162.  
  2163. --| Notes (none)
  2164. --|
  2165. --| Modifications
  2166. --| 08/16/89  Rick Conn    Initial Version
  2167.  
  2168.   Is_Open
  2169.     : BOOLEAN
  2170.       := false;
  2171.  
  2172.   Error_File
  2173.     : Output_File.File_Type;
  2174.  
  2175.   Output_To_Stdio
  2176.     : BOOLEAN
  2177.       := false;
  2178.  
  2179.   Error_Count
  2180.     : NATURAL
  2181.       := 0;
  2182.  
  2183.   Warning_Count
  2184.     : NATURAL
  2185.       := 0;
  2186.  
  2187.   -- ..................................
  2188.   -- .                                .
  2189.   -- .  Open                          .  BODY
  2190.   -- .                                .
  2191.   -- ..................................
  2192.  
  2193.   procedure Open
  2194.     ( File_Name      : in STRING ) is
  2195.  
  2196.   --| Notes (none)
  2197.  
  2198.   begin -- Open
  2199.  
  2200.     if File_Name'Length > 0 then
  2201.       Output_File.Create(Error_File, File_Name);
  2202.       Is_Open        := true;
  2203.       Output_To_Stdio := false;
  2204.     else
  2205.       Is_Open        := true;
  2206.       Output_To_Stdio := true;
  2207.     end if;
  2208.  
  2209.   exception -- Open -- Open -- Open
  2210.     when others =>
  2211.       Is_Open        := true;
  2212.       Output_To_Stdio := true;
  2213.  
  2214.   end Open;
  2215.  
  2216.   -- ..................................
  2217.   -- .                                .
  2218.   -- .  Write_Location                .  SPEC & BODY
  2219.   -- .                                .
  2220.   -- ..................................
  2221.   procedure Write_Location is
  2222.  
  2223.   --| Notes (none)
  2224.  
  2225.   begin -- Write_Location
  2226.  
  2227.     if Output_To_Stdio then
  2228.       Console.Put_Line("(" & Variable.Get_File_Name & ":"
  2229.           & NATURAL'Image(Variable.Line_Number) & ")");
  2230.     else
  2231.       Output_File.Put_Line(Error_File, "(" & Variable.Get_File_Name
  2232.           & ":" & NATURAL'Image(Variable.Line_Number) & ")");
  2233.     end if;
  2234.  
  2235.   end Write_Location;
  2236.  
  2237.   -- ..................................
  2238.   -- .                                .
  2239.   -- .  Write_Error                   .  BODY
  2240.   -- .                                .
  2241.   -- ..................................
  2242.   procedure Write_Error
  2243.     ( Message        : in STRING ) is
  2244.  
  2245.   --| Notes (none)
  2246.  
  2247.   begin -- Write_Error
  2248.  
  2249.     if not Is_Open then
  2250.       Open("");
  2251.     end if;
  2252.     if Output_To_Stdio then
  2253.       Console.Put("Error   : " & Message);
  2254.     else
  2255.       Output_File.Put(Error_File, "Error   : " & Message);
  2256.     end if;
  2257.     Write_Location;
  2258.     Error_Count    := Error_Count + 1;
  2259.  
  2260.   end Write_Error;
  2261.  
  2262.   -- ..................................
  2263.   -- .                                .
  2264.   -- .  Write_Warning                 .  BODY
  2265.   -- .                                .
  2266.   -- ..................................
  2267.   procedure Write_Warning
  2268.     ( Message        : in STRING ) is
  2269.  
  2270.   --| Notes (none)
  2271.  
  2272.   begin -- Write_Warning
  2273.  
  2274.     if not Is_Open then
  2275.       Open("");
  2276.     end if;
  2277.     if Output_To_Stdio then
  2278.       Console.Put("Warning : " & Message);
  2279.     else
  2280.       Output_File.Put(Error_File, "Warning : " & Message);
  2281.     end if;
  2282.     Write_Location;
  2283.     Warning_Count  := Warning_Count + 1;
  2284.  
  2285.   end Write_Warning;
  2286.  
  2287.   -- ..................................
  2288.   -- .                                .
  2289.   -- .  Close                         .  BODY
  2290.   -- .                                .
  2291.   -- ..................................
  2292.   procedure Close is
  2293.  
  2294.   --| Notes (none)
  2295.  
  2296.   begin -- Close
  2297.  
  2298.     if Is_Open then
  2299.       if not Output_To_Stdio then
  2300.         Output_File.Close(Error_File);
  2301.       end if;
  2302.     end if;
  2303.     Console.Put("  ");
  2304.     if Error_Count = 0 then
  2305.       Console.Put("No Errors, ");
  2306.     else
  2307.       Console.Put(NATURAL'Image(Error_Count) & " Error(s), ");
  2308.     end if;
  2309.     if Warning_Count = 0 then
  2310.       Console.Put("No Warnings");
  2311.     else
  2312.       Console.Put(NATURAL'Image(Warning_Count) & " Warning(s)");
  2313.     end if;
  2314.     Console.New_Line;
  2315.  
  2316.   end Close;
  2317.  
  2318. end Error_Log;
  2319. --::::::::::
  2320. --fof_body.a
  2321. --::::::::::
  2322. -- **********************************
  2323. -- *                                *
  2324. -- *  Formatted_Output_File         *  BODY
  2325. -- *                                *
  2326. -- **********************************
  2327. with Command_Symbols;
  2328. with Dyn;
  2329. with Error_Log;
  2330. with Output_File;
  2331. package body Formatted_Output_File is
  2332.  
  2333. --| Notes (none)
  2334. --|
  2335. --| Modifications
  2336. --| 08/16/89   Rick Conn    Initial version
  2337. --| 02/26/90   Rick Conn    Remove trailing spaces from @n
  2338.  
  2339.   subtype HF is
  2340.     Dyn.Dyn_String;
  2341.  
  2342.   type HF_SECTION is
  2343.     ( LEFT, CENTER, RIGHT );
  2344.  
  2345.   type HF_LINES is
  2346.     array (Header_Footer_Line, HF_SECTION)
  2347.       of HF;
  2348.  
  2349.   Header_Footer_Default
  2350.     : constant HF_LINES
  2351.       := (others         => (others         => Dyn.D_String(" ")));
  2352.  
  2353.   subtype LINE is                                -- very long line for
  2354.     STRING (1 .. Maximum_Line_Length * 5);       -- invisible words
  2355.  
  2356.   pragma Format_Off;
  2357.  
  2358.   type FILE_OBJECT is
  2359.     record
  2360.       Output_Is_Open : BOOLEAN   := false;  -- has file been opened?
  2361.       Output_Is_Empty : BOOLEAN;            -- has anything been output?
  2362.       Line_Is_Empty  : BOOLEAN;             -- is anything in Current_Line?
  2363.       Page_Attr      : Page_Attribute_List; -- left margin, etc.
  2364.       Line_Attr      : Line_Attribute_List; -- fill, etc (misnomer)
  2365.       Page_Num       : Page_Number;         -- # of current page
  2366.       Line_Num       : Line_Number;         -- # of line now being built
  2367.       Even_Header    : HF_LINES;            -- for even pages
  2368.       Odd_Header     : HF_LINES;            -- for odd pages
  2369.       Even_Footer    : HF_LINES;            -- for even pages
  2370.       Odd_Footer     : HF_LINES;            -- for odd pages
  2371.       Current_Line   : LINE;                -- line being built
  2372.       Index          : NATURAL;             -- index of next char to place
  2373.                                             --   into Current_Line
  2374.       Char_Count     : NATURAL;             -- number of visible chars
  2375.                                             --   in Current_Line
  2376.       Last_Char      : CHARACTER;           -- last char in Current_Line
  2377.       Page_Number_Id : CHARACTER;           -- xlates into page number
  2378.                                             --   in headers and footers
  2379.       Pn_Format      : Numeric_Format;      -- arabic, lower_ & upper_roman
  2380.       Pn_String      : Dyn.Dyn_String;      -- text of page number
  2381.       File_Id        : Output_File.File_Type; -- for Text_IO
  2382.     end record;
  2383.  
  2384.   pragma Format_On;
  2385.  
  2386.   use Command_Symbols;
  2387.  
  2388.   -- ..................................
  2389.   -- .                                .
  2390.   -- .  Is_Punctuation                .  SPEC & BODY
  2391.   -- .                                .
  2392.   -- ..................................
  2393.   function Is_Punctuation
  2394.     ( Item           : in CHARACTER )
  2395.       return BOOLEAN is
  2396.  
  2397.   --| Purpose
  2398.   --| Is_Punctuation returns TRUE if Item is one of the characters in
  2399.   --| PUNCTUATION_CHARS.
  2400.   --|
  2401.   --| Exceptions (none)
  2402.   --| Notes (none)
  2403.  
  2404.     Result
  2405.       : BOOLEAN
  2406.         := false;
  2407.  
  2408.   begin -- Is_Punctuation
  2409.  
  2410.     case Item is
  2411.       when '.' | ',' | '!' | '?' | ';' =>
  2412.         Result         := true;
  2413.       when others =>
  2414.         Result         := false;
  2415.     end case;
  2416.     return Result;
  2417.  
  2418.   end Is_Punctuation;
  2419.  
  2420.   -- ..................................
  2421.   -- .                                .
  2422.   -- .  Simple_Break_Page             .  SPEC
  2423.   -- .                                .
  2424.   -- ..................................
  2425.   procedure Simple_Break_Page
  2426.     ( Item           : in File );
  2427.  
  2428.   -- ..................................
  2429.   -- .                                .
  2430.   -- .  Pnum_As_String                .  SPEC & BODY
  2431.   -- .                                .
  2432.   -- ..................................
  2433.   function Pnum_As_String
  2434.     ( Value          : in Page_Number;
  2435.       Format         : in Numeric_Format )
  2436.       return STRING is
  2437.  
  2438.   --| Purpose
  2439.   --| Pnum_As_String outputs a string (with optional leading blanks)
  2440.   --| which contains the input number's representation in ARABIC,
  2441.   --| LOWER_ROMAN, or UPPER_ROMAN forms.
  2442.   --|
  2443.   --| Exceptions (none)
  2444.   --|
  2445.   --| Notes
  2446.   --| Value should be less than 1000 if output as a Roman numeral.
  2447.  
  2448.     Result
  2449.       : STRING (1 .. 20)
  2450.         := (others         => ' ');
  2451.  
  2452.     Rover                                        -- Set for leading space
  2453.       : NATURAL
  2454.         := Result'First;
  2455.  
  2456.     Ones
  2457.       : NATURAL
  2458.         := 0;
  2459.  
  2460.     Tens
  2461.       : NATURAL
  2462.         := 0;
  2463.  
  2464.     Hundreds
  2465.       : NATURAL
  2466.         := 0;
  2467.  
  2468.       -- ..................................
  2469.       -- .                                .
  2470.       -- .  Pnum_As_String.Put            .  SPEC & BODY
  2471.       -- .                                .
  2472.       -- ..................................
  2473.  
  2474.     procedure Put
  2475.       ( Item           : in CHARACTER ) is
  2476.  
  2477.     --| Purpose
  2478.     --| Put places a character into the Result buffer, incrementing Rover.
  2479.     --|
  2480.     --| Exceptions (none)
  2481.     --| Notes (none)
  2482.  
  2483.     begin -- Put
  2484.       Rover          := Rover + 1;
  2485.       Result(Rover)  := Item;
  2486.     end Put;
  2487.  
  2488.     -- ..................................
  2489.     -- .                                .
  2490.     -- .  Pnum_As_String.Output         .  SPEC & BODY
  2491.     -- .                                .
  2492.     -- ..................................
  2493.     procedure Output
  2494.       ( Value          : in NATURAL;
  2495.         Lower          : in CHARACTER;
  2496.         Middle         : in CHARACTER;
  2497.         Upper          : in CHARACTER ) is
  2498.  
  2499.     --| Purpose
  2500.     --| Output outputs the appropriate Roman characters representing
  2501.     --| Value into the string Result, incrementing the pointer Rover
  2502.     --| as it goes.  Value must be between 1 and 9, inclusive.
  2503.     --|
  2504.     --| Exceptions (none)
  2505.     --| Notes (none)
  2506.  
  2507.     begin -- Output
  2508.  
  2509.       if Value < 4 then
  2510.         for I in 1 .. Value loop
  2511.           Put(Lower);
  2512.         end loop;
  2513.       elsif Value = 4 then
  2514.         Put(Lower);
  2515.         Put(Middle);
  2516.       elsif (Value >= 5) and (Value < 9) then
  2517.         Put(Middle);
  2518.         if Value > 5 then
  2519.           for I in 1 .. Value - 5 loop
  2520.             Put(Lower);
  2521.           end loop;
  2522.         end if;
  2523.       else
  2524.         Put(Lower);
  2525.         Put(Upper);
  2526.       end if;
  2527.  
  2528.     end Output;
  2529.  
  2530.     -- ..................................
  2531.     -- .                                .
  2532.     -- .  Pnum_As_String.Divide         .  SPEC & BODY
  2533.     -- .                                .
  2534.     -- ..................................
  2535.     procedure Divide
  2536.       ( Value          : in NATURAL ) is
  2537.  
  2538.     --| Purpose
  2539.     --| Divide sets the number of Thousands, Hundreds, Tens, and Ones
  2540.     --| in the passed value for Roman numeral computation.
  2541.     --|
  2542.     --| Exceptions (none)
  2543.     --| Notes (none)
  2544.  
  2545.       Temp
  2546.         : NATURAL
  2547.           := Value;
  2548.  
  2549.     begin -- Divide
  2550.  
  2551.       if Temp >= 100 then
  2552.         Hundreds       := Temp / 100;
  2553.         Temp           := Temp - Hundreds * 100;
  2554.       end if;
  2555.       if Temp >= 10 then
  2556.         Tens           := Temp / 10;
  2557.         Temp           := Temp - Tens * 10;
  2558.       end if;
  2559.       Ones           := Temp;
  2560.  
  2561.     end Divide;
  2562.  
  2563.   begin -- Pnum_As_String
  2564.  
  2565.     case Format is
  2566.  
  2567.       when Arabic =>
  2568.         return Page_Number'Image(Value);
  2569.  
  2570.       when Lower_Roman =>
  2571.         if NATURAL(Value) >= 1000 then
  2572.           Put('z');
  2573.           Put('z');
  2574.           Put('z');
  2575.         else
  2576.           Divide(NATURAL(Value));
  2577.           if Hundreds > 0 then
  2578.             Output(Hundreds, 'c', 'd', 'm');
  2579.           end if;
  2580.           if Tens > 0 then
  2581.             Output(Tens, 'x', 'l', 'c');
  2582.           end if;
  2583.           if Ones > 0 then
  2584.             Output(Ones, 'i', 'v', 'x');
  2585.           end if;
  2586.         end if;
  2587.  
  2588.       when Upper_Roman =>
  2589.         if NATURAL(Value) >= 1000 then
  2590.           Put('Z');
  2591.           Put('Z');
  2592.           Put('Z');
  2593.         else
  2594.           Divide(NATURAL(Value));
  2595.           if Hundreds > 0 then
  2596.             Output(Hundreds, 'C', 'D', 'M');
  2597.           end if;
  2598.           if Tens > 0 then
  2599.             Output(Tens, 'X', 'L', 'C');
  2600.           end if;
  2601.           if Ones > 0 then
  2602.             Output(Ones, 'I', 'V', 'X');
  2603.           end if;
  2604.         end if;
  2605.  
  2606.     end case;
  2607.  
  2608.     return Result(1 .. Rover);
  2609.  
  2610.   exception
  2611.     when others =>
  2612.       Error_Log.Write_Error(Error_Internal_Pnum);
  2613.       return " ";
  2614.  
  2615.   end Pnum_As_String;
  2616.  
  2617.   -- ..................................
  2618.   -- .                                .
  2619.   -- .  Start_Line                    .  SPEC & BODY
  2620.   -- .                                .
  2621.   -- ..................................
  2622.   procedure Start_Line
  2623.     ( Item           : in File ) is
  2624.  
  2625.   --| Purpose
  2626.   --| This is an internal routine not specified in the package
  2627.   --| specification.  It is used to initialize the Current_Line
  2628.   --| field of the Item object and the associated fields.  It sets
  2629.   --| the left margin.
  2630.   --|
  2631.   --| Exceptions (none)
  2632.   --| Notes (none)
  2633.  
  2634.   begin -- Start_Line
  2635.  
  2636.     if Item.Page_Attr(Temp_Indent) > 0 then
  2637.       Item.Index     := Item.Page_Attr(Temp_Indent)
  2638.           + Item.Page_Attr(Page_Offset);
  2639.       Item.Page_Attr(Temp_Indent) := 0;
  2640.     else
  2641.       Item.Index     := Item.Page_Attr(Left_Margin)
  2642.           + Item.Page_Attr(Left_Indent) + Item.Page_Attr(Page_Offset);
  2643.     end if;
  2644.     if Item.Index < 1 then
  2645.       Item.Index     := 1;
  2646.     end if;
  2647.     Item.Char_Count := Item.Index - 1;
  2648.     Item.Current_Line(1 .. Item.Index) := (others         => ' ');
  2649.     Item.Last_Char := ' ';
  2650.     Item.Line_Is_Empty := false;
  2651.  
  2652.   end Start_Line;
  2653.  
  2654.   -- ..................................
  2655.   -- .                                .
  2656.   -- .  Space_Lines                   .  SPEC & BODY
  2657.   -- .                                .
  2658.   -- ..................................
  2659.   procedure Space_Lines
  2660.     ( Item           : in File ) is
  2661.  
  2662.   --| Purpose
  2663.   --| This is an internal routine not specified in the package
  2664.   --| specification.  It is used to output additional blank lines
  2665.   --| based on the LINE_SPACING setting.
  2666.   --|
  2667.   --| Exceptions (none)
  2668.   --| Notes (none)
  2669.  
  2670.   begin -- Space_Lines
  2671.  
  2672.     if Item.Page_Attr(Line_Spacing) > 0 then
  2673.       if Test_Page(Item, Line_Number(Item.Page_Attr(Line_Spacing))) then
  2674.         for I in 1 .. Item.Page_Attr(Line_Spacing) loop
  2675.           Output_File.New_Line(Item.File_Id);
  2676.           Item.Line_Num  := Item.Line_Num + 1;
  2677.         end loop;
  2678.       else
  2679.         Simple_Break_Page(Item);
  2680.       end if;
  2681.     end if;
  2682.  
  2683.   end Space_Lines;
  2684.  
  2685.   -- ..................................
  2686.   -- .                                .
  2687.   -- .  Justify_Line                  .  SPEC & BODY
  2688.   -- .                                .
  2689.   -- ..................................
  2690.   procedure Justify_Line
  2691.     ( Item           : in File ) is
  2692.  
  2693.   --| Notes
  2694.   --| This is an internal routine not specified in the package
  2695.   --| specification.  It is used to fill the Current_Line
  2696.   --| with spaces so that the last character is on the right
  2697.   --| margin.
  2698.   --|
  2699.   --| Exceptions (none)
  2700.   --| Notes (none)
  2701.  
  2702.     Spaces_Required
  2703.       : constant NATURAL
  2704.         := Item.Page_Attr(Right_Margin) - Item.Page_Attr(Right_Indent)
  2705.           - Item.Char_Count + Item.Page_Attr(Page_Offset);
  2706.  
  2707.     Spaces_Left
  2708.       : NATURAL
  2709.         := Spaces_Required;
  2710.  
  2711.       -- ..................................
  2712.       -- .                                .
  2713.       -- .  Justify_Line.Justify          .  SPEC & BODY
  2714.       -- .                                .
  2715.       -- ..................................
  2716.  
  2717.     function Justify
  2718.       ( Amount_Left    : in NATURAL )
  2719.         return NATURAL is
  2720.  
  2721.     --| Purpose
  2722.     --| Justify replaces single spaces in Item.Current_Line with
  2723.     --| double spaces until Amount is zero or the end of the
  2724.     --| line is reached.
  2725.     --|
  2726.     --| Exceptions (none)
  2727.     --| Notes (none)
  2728.  
  2729.       type PARSE_STATE is
  2730.         ( BEFORE_TEXT, IN_TEXT, IN_SPACES, DONE );
  2731.  
  2732.       State
  2733.         : PARSE_STATE
  2734.           := BEFORE_TEXT;
  2735.  
  2736.       I                                          -- index for Temp
  2737.         : NATURAL;
  2738.  
  2739.       Amount                                     -- number of spaces to go
  2740.         : NATURAL
  2741.           := Amount_Left;
  2742.  
  2743.       Temp
  2744.         : LINE;
  2745.  
  2746.       Was_In_Spaces
  2747.         : BOOLEAN
  2748.           := false;
  2749.  
  2750.     begin -- Justify
  2751.  
  2752.       I              := 1;
  2753.       for J in 1 .. Item.Index - 1 loop
  2754.         case State is
  2755.           when BEFORE_TEXT =>
  2756.             Temp(I)        := Item.Current_Line(J);
  2757.             I              := I + 1;
  2758.             if Item.Current_Line(J) > ' ' then
  2759.               State          := IN_TEXT;
  2760.             end if;
  2761.           when IN_TEXT =>
  2762.             if Item.Current_Line(J) = ' ' then
  2763.               Temp(I)        := ' ';
  2764.               I              := I + 1;
  2765.               Temp(I)        := ' ';
  2766.               I              := I + 1;
  2767.               Amount         := Amount - 1;
  2768.               Was_In_Spaces  := true;
  2769.               if Amount = 0 then
  2770.                 State          := DONE;
  2771.               else
  2772.                 State          := IN_SPACES;
  2773.               end if;
  2774.             else
  2775.               Temp(I)        := Item.Current_Line(J);
  2776.               I              := I + 1;
  2777.             end if;
  2778.           when IN_SPACES =>
  2779.             Temp(I)        := Item.Current_Line(J);
  2780.             I              := I + 1;
  2781.             if Item.Current_Line(J) /= ' ' then
  2782.               State          := IN_TEXT;
  2783.             end if;
  2784.           when DONE =>
  2785.             Temp(I)        := Item.Current_Line(J);
  2786.             I              := I + 1;
  2787.         end case;
  2788.       end loop;
  2789.  
  2790.       Item.Current_Line := Temp;
  2791.       Item.Index     := I;
  2792.       if not Was_In_Spaces then
  2793.         Amount         := 0;
  2794.       end if;
  2795.       return Amount;
  2796.  
  2797.     end Justify;
  2798.  
  2799.   begin -- Justify_Line
  2800.  
  2801.     while Spaces_Left > 0 loop
  2802.       Spaces_Left    := Justify(Spaces_Left);
  2803.     end loop;
  2804.  
  2805.   end Justify_Line;
  2806.  
  2807.   -- ..................................
  2808.   -- .                                .
  2809.   -- .  Conditional_Break_Page        .  SPEC & BODY
  2810.   -- .                                .
  2811.   -- ..................................
  2812.   procedure Conditional_Break_Page
  2813.     ( Item           : in File ) is
  2814.  
  2815.   --| Purpose
  2816.   --| Checks to see if there are any lines left on the page and
  2817.   --| calls Break_Page if not.
  2818.   --|
  2819.   --| Exceptions (none)
  2820.   --| Notes (none)
  2821.  
  2822.   begin -- Conditional_Break_Page
  2823.  
  2824.     if INTEGER(Item.Line_Num) > Item.Page_Attr(Total_Lines)
  2825.         - (Item.Page_Attr(Bottom_Margin) + Item.Page_Attr(Footer_Lines)) then
  2826.       Simple_Break_Page(Item);
  2827.     end if;
  2828.  
  2829.   end Conditional_Break_Page;
  2830.  
  2831.   -- ..................................
  2832.   -- .                                .
  2833.   -- .  Put_Header_Footer_Line        .  SPEC & BODY
  2834.   -- .                                .
  2835.   -- ..................................
  2836.   procedure Put_Header_Footer_Line
  2837.     ( Item           : in File;
  2838.       Left_Text      : in STRING;
  2839.       Center_Text    : in STRING;
  2840.       Right_Text     : in STRING;
  2841.       Page_Num       : in STRING ) is
  2842.  
  2843.   --| Purpose
  2844.   --| This is an internal routine not specified in the package
  2845.   --| specification.  It outputs a header or a footer line, placing
  2846.   --| the Page_Num string (which MUST be created by Current_Page) into
  2847.   --| it wherever the Item.Page_Number_Id character is found.  The
  2848.   --| Left_Text string is left-justified against the left margin
  2849.   --| (first character starts on the left margin), the Center_Text
  2850.   --| string is centered between the left and right margins, and
  2851.   --| the Right_Text string is right-justified against the right
  2852.   --| margin (the last character falls on the right margin).
  2853.   --|
  2854.   --| Exceptions (none)
  2855.   --| Notes (none)
  2856.  
  2857.     Hf_Line
  2858.       : LINE
  2859.         := (others         => ' ');
  2860.  
  2861.     Hf_Last
  2862.       : NATURAL
  2863.         := Item.Page_Attr(Right_Margin) + Item.Page_Attr(Page_Offset);
  2864.  
  2865.     Hf_Last_Save
  2866.       : NATURAL;
  2867.  
  2868.     Left_Text_Lower
  2869.       : constant NATURAL
  2870.         := Item.Page_Attr(Left_Margin) + Item.Page_Attr(Page_Offset);
  2871.  
  2872.     Left_Text_Upper
  2873.       : NATURAL;
  2874.  
  2875.     Right_Text_Lower
  2876.       : NATURAL;
  2877.  
  2878.     Right_Text_Upper
  2879.       : constant NATURAL
  2880.         := Item.Page_Attr(Right_Margin) + Item.Page_Attr(Page_Offset);
  2881.  
  2882.     Center_Point
  2883.       : constant NATURAL
  2884.         := (Right_Text_Upper - Left_Text_Lower) / 2 + Left_Text_Lower;
  2885.  
  2886.     Center_Text_Lower
  2887.       : NATURAL;
  2888.  
  2889.     Center_Text_Upper
  2890.       : NATURAL;
  2891.  
  2892.     Temp_String
  2893.       : LINE;
  2894.  
  2895.     Temp_Length
  2896.       : NATURAL;
  2897.  
  2898.       -- ..............................................
  2899.       -- .                                            .
  2900.       -- .  Put_Header_Footer_Line.Build_Temp_String  .  SPEC & BODY
  2901.       -- .                                            .
  2902.       -- ..............................................
  2903.  
  2904.     procedure Build_Temp_String
  2905.       ( Str            : in STRING ) is
  2906.  
  2907.     --| Purpose
  2908.     --| Build_Temp_String analyzes the input string for the Page_Number_Id
  2909.     --| character, building a new output string in the global Temp_String
  2910.     --| vector which contains the input string with the literal page
  2911.     --| number substituted for the Page_Number_Id character.
  2912.     --|
  2913.     --| Exceptions (none)
  2914.     --| Notes (none)
  2915.  
  2916.       J
  2917.         : NATURAL
  2918.           := 1;
  2919.  
  2920.     begin -- Build_Temp_String
  2921.  
  2922.       for I in Str'First .. Str'Last loop
  2923.         if Str(I) = Item.Page_Number_Id then
  2924.           for K in Page_Num'Range loop
  2925.             Temp_String(J) := Page_Num(K);
  2926.             J              := J + 1;
  2927.           end loop;
  2928.         else
  2929.           Temp_String(J) := Str(I);
  2930.           J              := J + 1;
  2931.         end if;
  2932.       end loop;
  2933.       Temp_Length    := J - 1;
  2934.       J := 0;
  2935.       -- remove trailing spaces
  2936.       for I in reverse 1 .. Temp_Length loop
  2937.         if Temp_String(I) > ' ' then
  2938.           J := I;
  2939.           exit;
  2940.         end if;
  2941.       end loop;
  2942.       Temp_Length := J;
  2943.  
  2944.       Left_Text_Upper := Item.Page_Attr(Left_Margin) + Temp_Length - 1
  2945.           + Item.Page_Attr(Page_Offset);
  2946.  
  2947.       Right_Text_Lower := Item.Page_Attr(Right_Margin) - Temp_Length + 1
  2948.           + Item.Page_Attr(Page_Offset);
  2949.  
  2950.       Center_Text_Lower := Center_Point - Temp_Length / 2;
  2951.  
  2952.       Center_Text_Upper := Center_Text_Lower + Temp_Length - 1;
  2953.  
  2954.     end Build_Temp_String;
  2955.  
  2956.   begin -- Put_Header_Footer_Line
  2957.  
  2958.     if Left_Text'Length > 0 then
  2959.       Build_Temp_String(Left_Text);
  2960.       if Temp_Length < Right_Text_Upper - Left_Text_Lower + 1 then
  2961.         Hf_Line(Left_Text_Lower .. Left_Text_Upper) := Temp_String(1 ..
  2962.             Temp_Length);
  2963.       else
  2964.         Hf_Line(Left_Text_Lower .. Right_Text_Upper) := Temp_String(1 ..
  2965.             (Right_Text_Upper - Left_Text_Lower + 1));
  2966.       end if;
  2967.     end if;
  2968.     if Right_Text'Length > 0 then
  2969.       Build_Temp_String(Right_Text);
  2970.       if Temp_Length < Right_Text_Upper - Left_Text_Lower + 1 then
  2971.         Hf_Line(Right_Text_Lower .. Right_Text_Upper) := Temp_String(1 ..
  2972.             Temp_Length);
  2973.       else
  2974.         Hf_Line(Left_Text_Lower .. Right_Text_Upper) := Temp_String(1 ..
  2975.             (Right_Text_Upper - Left_Text_Lower + 1));
  2976.       end if;
  2977.     end if;
  2978.     if Center_Text'Length > 0 then
  2979.       Build_Temp_String(Center_Text);
  2980.       if Temp_Length < Right_Text_Upper - Left_Text_Lower + 1 then
  2981.         Hf_Line(Center_Text_Lower .. Center_Text_Upper) := Temp_String(1 ..
  2982.             Temp_Length);
  2983.       else
  2984.         Hf_Line(Left_Text_Lower .. Right_Text_Upper) := Temp_String(1 ..
  2985.             (Right_Text_Upper - Left_Text_Lower + 1));
  2986.       end if;
  2987.     end if;
  2988.     Hf_Last_Save   := Hf_Last;
  2989.     Hf_Last        := 1;
  2990.     for I in reverse 1 .. Hf_Last_Save loop
  2991.       if Hf_Line(I) /= ' ' then
  2992.         Hf_Last        := I;
  2993.         exit;
  2994.       end if;
  2995.     end loop;
  2996.     Output_File.Put_Line(Item.File_Id, Hf_Line(1 .. Hf_Last));
  2997.     Item.Line_Num  := Item.Line_Num + 1;
  2998.  
  2999.   exception
  3000.     when others =>
  3001.       Error_Log.Write_Error(Error_Internal_Hf_Line);
  3002.  
  3003.   end Put_Header_Footer_Line;
  3004.  
  3005.   -- ..................................
  3006.   -- .                                .
  3007.   -- .  Output_Top_Of_Page            .  SPEC & BODY
  3008.   -- .                                .
  3009.   -- ..................................
  3010.   procedure Output_Top_Of_Page
  3011.     ( Item           : in File ) is
  3012.  
  3013.   --| Purpose
  3014.   --| This is an internal routine not specified in the package
  3015.   --| specification.  Assuming that the output is at the top
  3016.   --| of page, it increments the Item.Page_Num, outputs
  3017.   --| the appropriate number of blank lines as per the Top_Margin,
  3018.   --| and outputs the header lines (distinguishing between even and
  3019.   --| odd pages).
  3020.   --|
  3021.   --| Exceptions (none)
  3022.   --| Notes (none)
  3023.  
  3024.     Is_Even
  3025.       : BOOLEAN;
  3026.  
  3027.   begin -- Output_Top_Of_Page
  3028.  
  3029.     Item.Line_Num  := 1;
  3030.     if Item.Page_Attr(Top_Margin) > 0 then
  3031.       for I in 1 .. Item.Page_Attr(Top_Margin) loop
  3032.         Output_File.New_Line(Item.File_Id);
  3033.         Item.Line_Num  := Item.Line_Num + 1;
  3034.       end loop;
  3035.     end if;
  3036.     if Item.Page_Attr(Header_Lines) > 0 then
  3037.       if Item.Page_Num / 2 * 2 = Item.Page_Num then
  3038.         Is_Even        := true;
  3039.       else
  3040.         Is_Even        := false;
  3041.       end if;
  3042.       for I in 1 .. Header_Footer_Line(Item.Page_Attr(Header_Lines)) loop
  3043.         if Is_Even then
  3044.           Put_Header_Footer_Line(Item, Dyn.Str(Item.Even_Header(I, LEFT)),
  3045.               Dyn.Str(Item.Even_Header(I, CENTER)),
  3046.               Dyn.Str(Item.Even_Header(I, RIGHT)),
  3047.               Current_Page(Item));
  3048.         else
  3049.           Put_Header_Footer_Line(Item, Dyn.Str(Item.Odd_Header(I, LEFT)),
  3050.               Dyn.Str(Item.Odd_Header(I, CENTER)),
  3051.               Dyn.Str(Item.Odd_Header(I, RIGHT)),
  3052.               Current_Page(Item));
  3053.         end if;
  3054.       end loop;
  3055.     end if;
  3056.  
  3057.   exception
  3058.     when others =>
  3059.       Error_Log.Write_Error(Error_Internal_Top);
  3060.  
  3061.   end Output_Top_Of_Page;
  3062.  
  3063.   -- ..................................
  3064.   -- .                                .
  3065.   -- .  Output_Bottom_Of_Page         .  BODY
  3066.   -- .                                .
  3067.   -- ..................................
  3068.   procedure Output_Bottom_Of_Page
  3069.     ( Item           : in File ) is
  3070.  
  3071.   --| Purpose
  3072.   --| Output_Bottom_Of_Page determines how many blank lines are left
  3073.   --| in the text area (between the top margin/header combination and
  3074.   --| the bottom margin/footer combination) and outputs blank lines in
  3075.   --| order to reach the first footer line.  It then outputs the
  3076.   --| footer (distinguishing between even and odd page footers) and
  3077.   --| advances over the bottom margin (with either blank lines or
  3078.   --| form feeds).
  3079.   --|
  3080.   --| Exceptions (none)
  3081.   --| Notes (none)
  3082.  
  3083.     Lines_Left
  3084.       : Line_Number;
  3085.  
  3086.     Is_Even
  3087.       : BOOLEAN;
  3088.  
  3089.   begin -- Output_Bottom_Of_Page
  3090.  
  3091.     Lines_Left     := Line_Number(Item.Page_Attr(Total_Lines)
  3092.         - (Item.Page_Attr(Bottom_Margin) + Item.Page_Attr(Footer_Lines)))
  3093.         - Item.Line_Num + 1;
  3094.     if Lines_Left < 0 then
  3095.       Lines_Left     := 0;
  3096.     end if;
  3097.     if Lines_Left > 0 then
  3098.       for I in 1 .. Lines_Left loop
  3099.         Output_File.New_Line(Item.File_Id);
  3100.         Item.Line_Num  := Item.Line_Num + 1;
  3101.       end loop;
  3102.     end if;
  3103.     if Item.Page_Attr(Footer_Lines) > 0 then
  3104.       if Item.Page_Num / 2 * 2 = Item.Page_Num then
  3105.         Is_Even        := true;
  3106.       else
  3107.         Is_Even        := false;
  3108.       end if;
  3109.       for I in 1 .. Header_Footer_Line(Item.Page_Attr(Footer_Lines)) loop
  3110.         if Is_Even then
  3111.           Put_Header_Footer_Line(Item, Dyn.Str(Item.Even_Footer(I, LEFT)),
  3112.               Dyn.Str(Item.Even_Footer(I, CENTER)),
  3113.               Dyn.Str(Item.Even_Footer(I, RIGHT)),
  3114.               Current_Page(Item));
  3115.         else
  3116.           Put_Header_Footer_Line(Item, Dyn.Str(Item.Odd_Footer(I, LEFT)),
  3117.               Dyn.Str(Item.Odd_Footer(I, CENTER)),
  3118.               Dyn.Str(Item.Odd_Footer(I, RIGHT)),
  3119.               Current_Page(Item));
  3120.         end if;
  3121.       end loop;
  3122.     end if;
  3123.     if Item.Page_Attr(Bottom_Margin) > 0 then
  3124.       if Item.Line_Attr(Use_Form_Feed) = On then
  3125.         Output_File.New_Page(Item.File_Id);
  3126.       else
  3127.         for I in 1 .. Item.Page_Attr(Bottom_Margin) loop
  3128.           Output_File.New_Line(Item.File_Id);
  3129.           Item.Line_Num  := Item.Line_Num + 1;
  3130.         end loop;
  3131.       end if;
  3132.     end if;
  3133.  
  3134.   exception
  3135.     when others =>
  3136.       Error_Log.Write_Error(Error_Internal_Bottom);
  3137.  
  3138.   end Output_Bottom_Of_Page;
  3139.  
  3140.   -- ..................................
  3141.   -- .                                .
  3142.   -- .  Simple_Break_Page             .  BODY
  3143.   -- .                                .
  3144.   -- ..................................
  3145.   procedure Simple_Break_Page
  3146.     ( Item           : in File ) is
  3147.  
  3148.   --| Purpose
  3149.   --| Simple_Break_Page outputs to the bottom of the page and the
  3150.   --| top of the next page if paging is on.
  3151.   --|
  3152.   --| Exceptions (none)
  3153.   --| Notes (none)
  3154.  
  3155.   begin -- Simple_Break_Page
  3156.  
  3157.     if Item.Line_Attr(Paging) = On then
  3158.       Output_Bottom_Of_Page(Item);
  3159.       Item.Page_Num  := Item.Page_Num + 1;
  3160.       Output_Top_Of_Page(Item);
  3161.     else
  3162.       Item.Line_Num  := 1;
  3163.     end if;
  3164.  
  3165.   end Simple_Break_Page;
  3166.  
  3167.   -- ..................................
  3168.   -- .                                .
  3169.   -- .  Simple_Break_Page             .  SPEC & BODY
  3170.   -- .                                .
  3171.   -- ..................................
  3172.   procedure Simple_Break_Page
  3173.     ( Item           : in File;
  3174.       New_Page_Num   : in Page_Number ) is
  3175.  
  3176.   --| Purpose
  3177.   --| Simple_Break_Page outputs to the bottom of the page and the
  3178.   --| top of the next page if paging is on.  It sets the number of
  3179.   --| the new page to New_Page_Num.
  3180.   --|
  3181.   --| Exceptions (none)
  3182.   --| Notes (none)
  3183.  
  3184.   begin -- Simple_Break_Page
  3185.  
  3186.     if Item.Line_Attr(Paging) = On then
  3187.       Output_Bottom_Of_Page(Item);
  3188.       Item.Page_Num  := New_Page_Num;
  3189.       Output_Top_Of_Page(Item);
  3190.     else
  3191.       Item.Page_Num  := New_Page_Num;
  3192.       Item.Line_Num  := 1;
  3193.     end if;
  3194.  
  3195.   end Simple_Break_Page;
  3196.  
  3197.   -- ..................................
  3198.   -- .                                .
  3199.   -- .  Open                          .  BODY
  3200.   -- .                                .
  3201.   -- ..................................
  3202.  
  3203.   procedure Open
  3204.     ( Item           : in out File;
  3205.       File_Name      : in STRING;
  3206.       Result         : out Status ) is
  3207.  
  3208.   --| Notes
  3209.   --| Open the output file object and set
  3210.   --| defaults.  Map the Output_File.Open status to the
  3211.   --| Formatted_Output_File.Open status.
  3212.  
  3213.     Local_Result
  3214.       : Status;
  3215.  
  3216.   begin -- Open
  3217.  
  3218.     Item           := new FILE_OBJECT;
  3219.     begin
  3220.       Output_File.Create(Item.File_Id, File_Name);
  3221.       Local_Result   := Ok;
  3222.     exception
  3223.       when others =>
  3224.         Local_Result   := Not_Ok;
  3225.     end;
  3226.     if Local_Result = Ok then
  3227.       Item.Output_Is_Open := true;
  3228.       Item.Output_Is_Empty := true;
  3229.       Item.Line_Is_Empty := true;
  3230.       Item.Page_Attr := Page_Attribute_Defaults;
  3231.       Item.Line_Attr := Line_Attribute_Defaults;
  3232.       Item.Page_Num  := 0;
  3233.       Item.Line_Num  := 1;
  3234.       Item.Even_Header := Header_Footer_Default;
  3235.       Item.Odd_Header := Header_Footer_Default;
  3236.       Item.Even_Footer := Header_Footer_Default;
  3237.       Item.Odd_Footer := Header_Footer_Default;
  3238.       Item.Page_Number_Id := Page_Number_Id_Default;
  3239.       Item.Pn_Format := Arabic;
  3240.       Item.Pn_String := Dyn.D_String(Page_Number_Id_Default);
  3241.     else
  3242.       Item.Output_Is_Open := false;
  3243.     end if;
  3244.     Result         := Local_Result;
  3245.  
  3246.   end Open;
  3247.  
  3248.   -- ..................................
  3249.   -- .                                .
  3250.   -- .  Close                         .  BODY
  3251.   -- .                                .
  3252.   -- ..................................
  3253.   procedure Close
  3254.     ( Item           : in File ) is
  3255.  
  3256.   --| Notes (none)
  3257.  
  3258.   begin -- Close
  3259.  
  3260.     if not Item.Output_Is_Open then
  3261.       raise File_Not_Open;
  3262.     end if;
  3263.     if Item.Line_Attr(Paging) = On then
  3264.       Break_Line(Item);
  3265.       Output_Bottom_Of_Page(Item);
  3266.     else
  3267.       Item.Line_Num  := 1;
  3268.     end if;
  3269.     Output_File.Close(Item.File_Id);
  3270.     Item.Output_Is_Open := false;
  3271.  
  3272.   end Close;
  3273.  
  3274.   -- ..................................
  3275.   -- .                                .
  3276.   -- .  Put_Invisible_Word            .  BODY
  3277.   -- .                                .
  3278.   -- ..................................
  3279.   procedure Put_Invisible_Word
  3280.     ( Item           : in File;
  3281.       What           : in STRING ) is
  3282.  
  3283.   --| Notes (none)
  3284.  
  3285.   begin -- Put_Invisible_Word
  3286.     if not Item.Output_Is_Open then
  3287.       raise File_Not_Open;
  3288.     end if;
  3289.     if Item.Output_Is_Empty then
  3290.       if Item.Line_Attr(Paging) = On then
  3291.         Item.Page_Num  := Item.Page_Num + 1;
  3292.         Output_Top_Of_Page(Item);
  3293.       else
  3294.         Item.Line_Num  := 1;
  3295.       end if;
  3296.       Item.Output_Is_Empty := false;
  3297.     end if;
  3298.     if Item.Line_Is_Empty then
  3299.       Start_Line(Item);
  3300.     end if;
  3301.     Item.Current_Line(Item.Index .. Item.Index + What'Length - 1) := What;
  3302.     Item.Index     := Item.Index + What'Length;
  3303.  
  3304.   exception
  3305.     when others =>
  3306.       Error_Log.Write_Error(Error_Internal_Put_Invisible);
  3307.  
  3308.   end Put_Invisible_Word;
  3309.  
  3310.   -- ..................................
  3311.   -- .                                .
  3312.   -- .  Put_Word                      .  BODY
  3313.   -- .                                .
  3314.   -- ..................................
  3315.   procedure Put_Word
  3316.     ( Item           : in File;
  3317.       What           : in STRING ) is
  3318.  
  3319.   --| Notes (none)
  3320.  
  3321.     Adjustment_Length
  3322.       : NATURAL;
  3323.  
  3324.     Adjustment_String
  3325.       : constant STRING                          -- 2 spaces
  3326.         := "  ";
  3327.  
  3328.       -- ..................................
  3329.       -- .                                .
  3330.       -- .  Put_Word.Put_What             .  SPEC & BODY
  3331.       -- .                                .
  3332.       -- ..................................
  3333.  
  3334.     procedure Put_What is
  3335.  
  3336.     --| Notes
  3337.     --| Put_What is used to place the What string into Item.Current_Line
  3338.     --| and update the other variables as necessary.
  3339.  
  3340.       Full_Adjustment_Length
  3341.         : NATURAL
  3342.           := Adjustment_Length + What'Length;
  3343.  
  3344.       Full_String_Length
  3345.         : NATURAL
  3346.           := Item.Char_Count + Full_Adjustment_Length;
  3347.  
  3348.       Lower_Index
  3349.         : NATURAL
  3350.           := Item.Index;
  3351.  
  3352.       Upper_Index
  3353.         : NATURAL
  3354.           := Item.Index + Full_Adjustment_Length - 1;
  3355.  
  3356.     begin -- Put_What
  3357.  
  3358.       Item.Current_Line(Lower_Index .. Upper_Index) := Adjustment_String(1 ..
  3359.           Adjustment_Length) & What;
  3360.       Item.Index     := Upper_Index + 1;
  3361.       Item.Char_Count := Full_String_Length;
  3362.       Item.Last_Char := Item.Current_Line(Item.Index - 1);
  3363.       if Item.Line_Attr(Underline) = On then
  3364.         for I in 1 .. What'Length loop
  3365.           Item.Current_Line(Item.Index) := Ascii.Bs;
  3366.           Item.Index     := Item.Index + 1;
  3367.         end loop;
  3368.         for I in What'range loop
  3369.           if Item.Line_Attr(Underline_Punct) = Off then
  3370.             if Is_Punctuation(What(I)) then
  3371.               Item.Current_Line(Item.Index) := What(I);
  3372.             else
  3373.               Item.Current_Line(Item.Index) := '_';
  3374.             end if;
  3375.           else
  3376.             Item.Current_Line(Item.Index) := '_';
  3377.           end if;
  3378.           Item.Index     := Item.Index + 1;
  3379.         end loop;
  3380.       end if;
  3381.       if Item.Line_Attr(Bold) = On then
  3382.         for I in 1 .. What'Length loop
  3383.           Item.Current_Line(Item.Index) := Ascii.Bs;
  3384.           Item.Index     := Item.Index + 1;
  3385.         end loop;
  3386.         for I in What'range loop
  3387.           Item.Current_Line(Item.Index) := What(I);
  3388.           Item.Index     := Item.Index + 1;
  3389.         end loop;
  3390.       end if;
  3391.  
  3392.     exception
  3393.       when others =>
  3394.         Error_Log.Write_Error(Error_Internal_Put_What);
  3395.  
  3396.     end Put_What;
  3397.  
  3398.   begin -- Put_Word
  3399.  
  3400.     if not Item.Output_Is_Open then
  3401.       raise File_Not_Open;
  3402.     end if;
  3403.  
  3404.     if Item.Output_Is_Empty then
  3405.       if Item.Line_Attr(Paging) = On then
  3406.         Item.Page_Num  := Item.Page_Num + 1;
  3407.         Output_Top_Of_Page(Item);
  3408.       else
  3409.         Item.Line_Num  := 1;
  3410.       end if;
  3411.       Item.Output_Is_Empty := false;
  3412.     end if;
  3413.  
  3414.     if Item.Line_Is_Empty then
  3415.       Adjustment_Length := 0;
  3416.     else
  3417.       case Item.Last_Char is
  3418.         when ' ' =>
  3419.           Adjustment_Length := 0;
  3420.         when '.' =>
  3421.           Adjustment_Length := 2;
  3422.         when others =>
  3423.           Adjustment_Length := 1;
  3424.       end case;
  3425.     end if;
  3426.  
  3427.     if Item.Line_Attr(Fill) = On then
  3428.  
  3429.       if Item.Char_Count + Adjustment_Length + What'Length
  3430.           <= Item.Page_Attr(Right_Margin) - Item.Page_Attr(Right_Indent)
  3431.           + Item.Page_Attr(Page_Offset) then
  3432.  
  3433.         -- FILL is on and there is enough room on the line
  3434.         if Item.Line_Is_Empty then
  3435.           Start_Line(Item);
  3436.         end if;
  3437.         Put_What;
  3438.  
  3439.       else
  3440.  
  3441.         -- FILL is on, but not enough room on line
  3442.         if Item.Line_Attr(Justify) = On and not Item.Line_Is_Empty then
  3443.           Justify_Line(Item);
  3444.         end if;
  3445.         Break_Line(Item);
  3446.  
  3447.         Start_Line(Item);
  3448.         Adjustment_Length := 0;
  3449.         Put_What;
  3450.  
  3451.       end if;
  3452.  
  3453.     else
  3454.  
  3455.     -- No FILL, so no JUSTIFY either
  3456.       if Item.Line_Is_Empty then
  3457.         Start_Line(Item);
  3458.       end if;
  3459.       Put_What;
  3460.  
  3461.     end if;
  3462.  
  3463.   exception
  3464.     when others =>
  3465.       Error_Log.Write_Error(Error_Internal_Put_Word);
  3466.  
  3467.   end Put_Word;
  3468.  
  3469.   -- ..................................
  3470.   -- .                                .
  3471.   -- .  Put_Line                      .  BODY
  3472.   -- .                                .
  3473.   -- ..................................
  3474.   procedure Put_Line
  3475.     ( Item           : in File;
  3476.       What           : in STRING ) is
  3477.  
  3478.   --| Notes (none)
  3479.  
  3480.     First
  3481.       : NATURAL;
  3482.  
  3483.     Last
  3484.       : NATURAL;
  3485.  
  3486.     Temp
  3487.       : NATURAL;
  3488.  
  3489.     type PARSE_STATE is
  3490.       ( IN_WHITE_SPACE, IN_TEXT );
  3491.  
  3492.     Current_State
  3493.       : PARSE_STATE;
  3494.  
  3495.   begin -- Put_Line
  3496.  
  3497.     if not Item.Output_Is_Open then
  3498.       raise File_Not_Open;
  3499.     end if;
  3500.  
  3501.     if Item.Output_Is_Empty then
  3502.       if Item.Line_Attr(Paging) = On then
  3503.         Item.Page_Num  := Item.Page_Num + 1;
  3504.         Output_Top_Of_Page(Item);
  3505.       else
  3506.         Item.Line_Num  := 1;
  3507.       end if;
  3508.       Item.Output_Is_Empty := false;
  3509.     end if;
  3510.  
  3511.     if Item.Line_Attr(Fill) = Off then
  3512.  
  3513.     -- No FILL, so break previous line and output as a line
  3514.       Break_Line(Item);
  3515.       Conditional_Break_Page(Item);
  3516.       Start_Line(Item);                          -- for margin settings
  3517.       Item.Line_Is_Empty := true;
  3518.       if Item.Line_Attr(CENTER) = On then
  3519.         Temp           := (Item.Page_Attr(Right_Margin)
  3520.             - Item.Page_Attr(Right_Indent)) - (Item.Page_Attr(Left_Margin)
  3521.             + Item.Page_Attr(Left_Indent)) + 1;
  3522.         if Temp > What'Length then
  3523.           Temp           := (Temp - What'Length) / 2;
  3524.           for I in 1 .. Temp loop
  3525.             Output_File.Put(Item.File_Id, ' ');
  3526.           end loop;
  3527.         end if;
  3528.       end if;
  3529.       Output_File.Put(Item.File_Id, Item.Current_Line(1 .. Item.Char_Count)
  3530.           & What);
  3531.       if Item.Line_Attr(Bold) = On then
  3532.         for I in 1 .. What'Length loop
  3533.           Output_File.Put(Item.File_Id, Ascii.Bs);
  3534.         end loop;
  3535.         for I in What'range loop
  3536.           Output_File.Put(Item.File_Id, What(I));
  3537.         end loop;
  3538.       end if;
  3539.       if Item.Line_Attr(Underline) = On then
  3540.         for I in 1 .. What'Length loop
  3541.           Output_File.Put(Item.File_Id, Ascii.Bs);
  3542.         end loop;
  3543.         for I in What'range loop
  3544.           if What(I) > ' ' then
  3545.             if Item.Line_Attr(Underline_Punct) = Off then
  3546.               if Is_Punctuation(What(I)) then
  3547.                 Output_File.Put(Item.File_Id, What(I));
  3548.               else
  3549.                 Output_File.Put(Item.File_Id, '_');
  3550.               end if;
  3551.             else
  3552.               Output_File.Put(Item.File_Id, '_');
  3553.             end if;
  3554.           else
  3555.             Output_File.Put(Item.File_Id, What(I));
  3556.           end if;
  3557.         end loop;
  3558.       end if;
  3559.       Output_File.New_Line(Item.File_Id);
  3560.       Item.Line_Num  := Item.Line_Num + 1;
  3561.       Space_Lines(Item);
  3562.  
  3563.     else
  3564.  
  3565.     -- FILL, so parse out each word and use Put_Word to output
  3566.       Current_State  := IN_WHITE_SPACE;
  3567.       for I in What'First .. What'Last loop
  3568.         case Current_State is
  3569.           when IN_WHITE_SPACE =>
  3570.             if What(I) > ' ' then
  3571.               First          := I;
  3572.               Current_State  := IN_TEXT;
  3573.             end if;
  3574.           when IN_TEXT =>
  3575.             if What(I) <= ' ' then
  3576.               Last           := I - 1;
  3577.               Put_Word(Item, What(First .. Last));
  3578.               Current_State  := IN_WHITE_SPACE;
  3579.             end if;
  3580.         end case;
  3581.       end loop;
  3582.       if Current_State = IN_TEXT then
  3583.         Last           := What'Last;
  3584.         Put_Word(Item, What(First .. Last));
  3585.       end if;
  3586.  
  3587.     end if;
  3588.  
  3589.   exception
  3590.     when others =>
  3591.       Error_Log.Write_Error(Error_Internal_Put_Line);
  3592.  
  3593.   end Put_Line;
  3594.  
  3595.   -- ..................................
  3596.   -- .                                .
  3597.   -- .  Break_Line                    .  BODY
  3598.   -- .                                .
  3599.   -- ..................................
  3600.   procedure Break_Line
  3601.     ( Item           : in File ) is
  3602.  
  3603.   --| Notes
  3604.   --| Break_Line checks to see if the Current_Line is empty, and,
  3605.   --| if not, outputs it and sets the empty flag to TRUE.  Page
  3606.   --| breaks are also handled if necessary.
  3607.  
  3608.   begin -- Break_Line
  3609.  
  3610.     if not Item.Output_Is_Open then
  3611.       raise File_Not_Open;
  3612.     end if;
  3613.     if not Item.Line_Is_Empty then
  3614.       Conditional_Break_Page(Item);
  3615.       Output_File.Put_Line(Item.File_Id, Item.Current_Line(1 .. Item.Index
  3616.           - 1));
  3617.       Item.Line_Num  := Item.Line_Num + 1;
  3618.       Space_Lines(Item);
  3619.       Item.Line_Is_Empty := true;
  3620.     end if;
  3621.  
  3622.   exception
  3623.     when others =>
  3624.       Error_Log.Write_Error(Error_Internal_Break_Line);
  3625.  
  3626.   end Break_Line;
  3627.  
  3628.   -- ..................................
  3629.   -- .                                .
  3630.   -- .  Current_Line                  .  BODY
  3631.   -- .                                .
  3632.   -- ..................................
  3633.   function Current_Line
  3634.     ( Item           : in File )
  3635.       return Line_Number is
  3636.  
  3637.   --| Notes (none)
  3638.  
  3639.   begin -- Current_Line
  3640.  
  3641.     if not Item.Output_Is_Open then
  3642.       raise File_Not_Open;
  3643.     end if;
  3644.     return Item.Line_Num;
  3645.  
  3646.   end Current_Line;
  3647.  
  3648.   -- ..................................
  3649.   -- .                                .
  3650.   -- .  Skip                          .  BODY
  3651.   -- .                                .
  3652.   -- ..................................
  3653.   procedure Skip
  3654.     ( Item           : in File;
  3655.       Number_Of_Lines : in Line_Number := 1 ) is
  3656.  
  3657.   --| Notes (none)
  3658.  
  3659.   begin -- Skip
  3660.  
  3661.     if not Item.Output_Is_Open then
  3662.       raise File_Not_Open;
  3663.     end if;
  3664.     if Item.Output_Is_Empty then
  3665.       if Item.Line_Attr(Paging) = On then
  3666.         Item.Page_Num  := Item.Page_Num + 1;
  3667.         Output_Top_Of_Page(Item);
  3668.       else
  3669.         Item.Line_Num  := 1;
  3670.       end if;
  3671.       Item.Output_Is_Empty := false;
  3672.     end if;
  3673.     Break_Line(Item);
  3674.     if Test_Page(Item, Number_Of_Lines + Number_Of_Lines
  3675.         * Line_Number(Item.Page_Attr(Line_Spacing))) then
  3676.       for I in 1 .. Number_Of_Lines loop
  3677.         Output_File.New_Line(Item.File_Id);
  3678.         Item.Line_Num  := Item.Line_Num + 1;
  3679.         Space_Lines(Item);
  3680.       end loop;
  3681.     else
  3682.       Simple_Break_Page(Item);
  3683.     end if;
  3684.  
  3685.   exception
  3686.     when others =>
  3687.       Error_Log.Write_Error(Error_Internal_Skip);
  3688.  
  3689.   end Skip;
  3690.  
  3691.   -- ..................................
  3692.   -- .                                .
  3693.   -- .  Break_Page                    .  BODY
  3694.   -- .                                .
  3695.   -- ..................................
  3696.   procedure Break_Page
  3697.     ( Item           : in File ) is
  3698.  
  3699.   --| Notes
  3700.   --| Issues blank lines for the rest of the text area, outputs footer
  3701.   --| and bottom margin, and outputs header for next page.
  3702.  
  3703.   begin -- Break_Page
  3704.  
  3705.     if not Item.Output_Is_Open then
  3706.       raise File_Not_Open;
  3707.     end if;
  3708.     Break_Line(Item);
  3709.     Simple_Break_Page(Item);
  3710.  
  3711.   exception
  3712.     when others =>
  3713.       Error_Log.Write_Error(Error_Internal_Break_Page_1);
  3714.  
  3715.   end Break_Page;
  3716.  
  3717.   -- ..................................
  3718.   -- .                                .
  3719.   -- .  Break_Page                    .  BODY
  3720.   -- .                                .
  3721.   -- ..................................
  3722.   procedure Break_Page
  3723.     ( Item           : in File;
  3724.       New_Page_Num   : in Page_Number ) is
  3725.  
  3726.   --| Notes (none)
  3727.  
  3728.   begin -- Break_Page
  3729.  
  3730.     if not Item.Output_Is_Open then
  3731.       raise File_Not_Open;
  3732.     end if;
  3733.     Break_Line(Item);
  3734.     Simple_Break_Page(Item, New_Page_Num);
  3735.  
  3736.   exception
  3737.     when others =>
  3738.       Error_Log.Write_Error(Error_Internal_Break_Page_2);
  3739.  
  3740.   end Break_Page;
  3741.  
  3742.   -- ..................................
  3743.   -- .                                .
  3744.   -- .  Current_Page                  .  BODY
  3745.   -- .                                .
  3746.   -- ..................................
  3747.   function Current_Page
  3748.     ( Item           : in File )
  3749.       return Page_Number is
  3750.  
  3751.   --| Notes (none)
  3752.  
  3753.   begin -- Current_Page
  3754.  
  3755.     if not Item.Output_Is_Open then
  3756.       raise File_Not_Open;
  3757.     end if;
  3758.     return Item.Page_Num;
  3759.  
  3760.   end Current_Page;
  3761.  
  3762.   -- ..................................
  3763.   -- .                                .
  3764.   -- .  Current_Page                  .  BODY
  3765.   -- .                                .
  3766.   -- ..................................
  3767.   function Current_Page
  3768.     ( Item           : in FILE )
  3769.       return STRING is
  3770.  
  3771.   --| Notes (none)
  3772.  
  3773.     -- ..................................
  3774.     -- .                                .
  3775.     -- .  Current_Page.Convert          .  SPEC & BODY
  3776.     -- .                                .
  3777.     -- ..................................
  3778.     function Convert
  3779.       ( Page_Number : in STRING )
  3780.         return STRING is
  3781.  
  3782.       Result : STRING(1..80);
  3783.       Last : NATURAL := 0;
  3784.  
  3785.       -- ..................................
  3786.       -- .                                .
  3787.       -- .  Current_Page.Convert.Enter    .  SPEC & BODY
  3788.       -- .                                .
  3789.       -- ..................................
  3790.       procedure Enter
  3791.         ( Item : in STRING ) is
  3792.  
  3793.         Start : NATURAL := Item'First;
  3794.  
  3795.       begin -- Enter
  3796.  
  3797.         if Item(Start) = ' ' then
  3798.           Start := Start + 1;
  3799.         end if;
  3800.         for I in Start .. Item'Last loop
  3801.           Last := Last + 1;
  3802.           Result(Last) := Item(I);
  3803.         end loop;
  3804.  
  3805.       end Enter;
  3806.  
  3807.     begin -- Convert
  3808.  
  3809.       for I in Page_Number'Range loop
  3810.         if Page_Number(I) /= Item.Page_Number_Id then
  3811.           Last := Last + 1;
  3812.           Result(Last) := Page_Number(I);
  3813.         else
  3814.           Enter(Pnum_As_String(Item.Page_Num, Item.Pn_Format));
  3815.         end if;
  3816.       end loop;
  3817.       return Result(1..Last);
  3818.  
  3819.     end Convert;
  3820.  
  3821.   begin -- Current_Page
  3822.  
  3823.     if not Item.Output_Is_Open then
  3824.       raise File_Not_Open;
  3825.     end if;
  3826.     return Convert(Dyn.Str(Item.Pn_String));
  3827.  
  3828.   end Current_Page;
  3829.  
  3830.   -- ..................................
  3831.   -- .                                .
  3832.   -- .  Set_Page_Number_Format        .  BODY
  3833.   -- .                                .
  3834.   -- ..................................
  3835.   procedure Set_Page_Number_Format
  3836.     ( Item           : in File;
  3837.       To             : in NUMERIC_FORMAT;
  3838.       Format_String  : in STRING ) is
  3839.  
  3840.   --| Notes (none)
  3841.  
  3842.   begin -- Set_Page_Number_Format
  3843.  
  3844.     if not Item.Output_Is_Open then
  3845.       raise File_Not_Open;
  3846.     end if;
  3847.     Item.Pn_Format := To;
  3848.     if Format_String'Length > 0 then
  3849.       Dyn.Clear(Item.Pn_String);
  3850.       Item.Pn_String := Dyn.D_String(Format_String);
  3851.     end if;
  3852.  
  3853.   end Set_Page_Number_Format;
  3854.  
  3855.   -- ..................................
  3856.   -- .                                .
  3857.   -- .  Set_Page_Attribute            .  BODY
  3858.   -- .                                .
  3859.   -- ..................................
  3860.   procedure Set_Page_Attribute
  3861.     ( Item           : in File;
  3862.       What           : in Page_Attribute;
  3863.       To             : in NATURAL ) is
  3864.  
  3865.   --| Notes (none)
  3866.  
  3867.   begin -- Set_Page_Attribute
  3868.  
  3869.     if not Item.Output_Is_Open then
  3870.       raise File_Not_Open;
  3871.     end if;
  3872.     Item.Page_Attr(What) := To;
  3873.  
  3874.   end Set_Page_Attribute;
  3875.  
  3876.   -- ..................................
  3877.   -- .                                .
  3878.   -- .  Set_Line_Attribute            .  BODY
  3879.   -- .                                .
  3880.   -- ..................................
  3881.   procedure Set_Line_Attribute
  3882.     ( Item           : in File;
  3883.       What           : in Line_Attribute;
  3884.       To             : in Off_On ) is
  3885.  
  3886.   --| Notes (none)
  3887.  
  3888.   begin -- Set_Line_Attribute
  3889.  
  3890.     if not Item.Output_Is_Open then
  3891.       raise File_Not_Open;
  3892.     end if;
  3893.     Item.Line_Attr(What) := To;
  3894.     if What = CENTER then
  3895.       if To = On then
  3896.         Item.Line_Attr(Fill_State_Before_Center) := Item.Line_Attr(Fill);
  3897.         Item.Line_Attr(Fill) := Off;
  3898.       else
  3899.         Item.Line_Attr(Fill) := Item.Line_Attr(Fill_State_Before_Center);
  3900.       end if;
  3901.     end if;
  3902.  
  3903.   end Set_Line_Attribute;
  3904.  
  3905.   -- ..................................
  3906.   -- .                                .
  3907.   -- .  Get_Page_Attribute            .  BODY
  3908.   -- .                                .
  3909.   -- ..................................
  3910.   function Get_Page_Attribute
  3911.     ( Item           : in File;
  3912.       What           : in Page_Attribute )
  3913.       return NATURAL is
  3914.  
  3915.   --| Notes (none)
  3916.  
  3917.   begin -- Get_Page_Attribute
  3918.  
  3919.     if not Item.Output_Is_Open then
  3920.       raise File_Not_Open;
  3921.     end if;
  3922.     return Item.Page_Attr(What);
  3923.  
  3924.   end Get_Page_Attribute;
  3925.  
  3926.   -- ..................................
  3927.   -- .                                .
  3928.   -- .  Get_Line_Attribute            .  BODY
  3929.   -- .                                .
  3930.   -- ..................................
  3931.   function Get_Line_Attribute
  3932.     ( Item           : in File;
  3933.       What           : in Line_Attribute )
  3934.       return Off_On is
  3935.  
  3936.   --| Notes (none)
  3937.  
  3938.   begin -- Get_Line_Attribute
  3939.  
  3940.     if not Item.Output_Is_Open then
  3941.       raise File_Not_Open;
  3942.     end if;
  3943.     return Item.Line_Attr(What);
  3944.  
  3945.   end Get_Line_Attribute;
  3946.  
  3947.   -- ..................................
  3948.   -- .                                .
  3949.   -- .  Test_Page                     .  BODY
  3950.   -- .                                .
  3951.   -- ..................................
  3952.   function Test_Page
  3953.     ( Item           : in File;
  3954.       Number_Of_Lines : in Line_Number )
  3955.       return BOOLEAN is
  3956.  
  3957.   --| Notes (none)
  3958.  
  3959.   begin -- Test_Page
  3960.  
  3961.     if not Item.Output_Is_Open then
  3962.       raise File_Not_Open;
  3963.     end if;
  3964.     return INTEGER(Number_Of_Lines) <= Item.Page_Attr(Total_Lines) - (Item.
  3965.         Page_Attr(Bottom_Margin) + Item.Page_Attr(Footer_Lines))
  3966.         - INTEGER(Item.Line_Num);
  3967.  
  3968.   end Test_Page;
  3969.  
  3970.   -- ..................................
  3971.   -- .                                .
  3972.   -- .  Set_Footer_Line               .  BODY
  3973.   -- .                                .
  3974.   -- ..................................
  3975.   procedure Set_Footer_Line
  3976.     ( Item           : in File;
  3977.       Class          : in Page_Kind;
  3978.       Number         : in Header_Footer_Line;
  3979.       Left_Text      : in STRING;
  3980.       Center_Text    : in STRING;
  3981.       Right_Text     : in STRING ) is
  3982.  
  3983.   --| Notes (none)
  3984.  
  3985.   begin -- Set_Footer_Line
  3986.  
  3987.     if not Item.Output_Is_Open then
  3988.       raise File_Not_Open;
  3989.     end if;
  3990.     case Class is
  3991.       when Even_Pages =>
  3992.         Dyn.Clear(Item.Even_Footer(Number, LEFT));
  3993.         Item.Even_Footer(Number, LEFT) := Dyn.D_String(Left_Text);
  3994.         Dyn.Clear(Item.Even_Footer(Number, CENTER));
  3995.         Item.Even_Footer(Number, CENTER) := Dyn.D_String(Center_Text);
  3996.         Dyn.Clear(Item.Even_Footer(Number, RIGHT));
  3997.         Item.Even_Footer(Number, RIGHT) := Dyn.D_String(Right_Text);
  3998.       when Odd_Pages =>
  3999.         Dyn.Clear(Item.Odd_Footer(Number, LEFT));
  4000.         Item.Odd_Footer(Number, LEFT) := Dyn.D_String(Left_Text);
  4001.         Dyn.Clear(Item.Odd_Footer(Number, CENTER));
  4002.         Item.Odd_Footer(Number, CENTER) := Dyn.D_String(Center_Text);
  4003.         Dyn.Clear(Item.Odd_Footer(Number, RIGHT));
  4004.         Item.Odd_Footer(Number, RIGHT) := Dyn.D_String(Right_Text);
  4005.       when All_Pages =>
  4006.         Dyn.Clear(Item.Even_Footer(Number, LEFT));
  4007.         Item.Even_Footer(Number, LEFT) := Dyn.D_String(Left_Text);
  4008.         Dyn.Clear(Item.Even_Footer(Number, CENTER));
  4009.         Item.Even_Footer(Number, CENTER) := Dyn.D_String(Center_Text);
  4010.         Dyn.Clear(Item.Even_Footer(Number, RIGHT));
  4011.         Item.Even_Footer(Number, RIGHT) := Dyn.D_String(Right_Text);
  4012.         Dyn.Clear(Item.Odd_Footer(Number, LEFT));
  4013.         Item.Odd_Footer(Number, LEFT) := Dyn.D_String(Left_Text);
  4014.         Dyn.Clear(Item.Odd_Footer(Number, CENTER));
  4015.         Item.Odd_Footer(Number, CENTER) := Dyn.D_String(Center_Text);
  4016.         Dyn.Clear(Item.Odd_Footer(Number, RIGHT));
  4017.         Item.Odd_Footer(Number, RIGHT) := Dyn.D_String(Right_Text);
  4018.     end case;
  4019.  
  4020.   exception
  4021.     when others =>
  4022.       Error_Log.Write_Error(Error_Internal_Set_Footer_Line);
  4023.  
  4024.   end Set_Footer_Line;
  4025.  
  4026.   -- ..................................
  4027.   -- .                                .
  4028.   -- .  Set_Header_Line               .  BODY
  4029.   -- .                                .
  4030.   -- ..................................
  4031.   procedure Set_Header_Line
  4032.     ( Item           : in File;
  4033.       Class          : in Page_Kind;
  4034.       Number         : in Header_Footer_Line;
  4035.       Left_Text      : in STRING;
  4036.       Center_Text    : in STRING;
  4037.       Right_Text     : in STRING ) is
  4038.  
  4039.   --| Notes (none)
  4040.  
  4041.   begin -- Set_Header_Line
  4042.  
  4043.     if not Item.Output_Is_Open then
  4044.       raise File_Not_Open;
  4045.     end if;
  4046.     case Class is
  4047.       when Even_Pages =>
  4048.         Dyn.Clear(Item.Even_Header(Number, LEFT));
  4049.         Item.Even_Header(Number, LEFT) := Dyn.D_String(Left_Text);
  4050.         Dyn.Clear(Item.Even_Header(Number, CENTER));
  4051.         Item.Even_Header(Number, CENTER) := Dyn.D_String(Center_Text);
  4052.         Dyn.Clear(Item.Even_Header(Number, RIGHT));
  4053.         Item.Even_Header(Number, RIGHT) := Dyn.D_String(Right_Text);
  4054.       when Odd_Pages =>
  4055.         Dyn.Clear(Item.Odd_Header(Number, LEFT));
  4056.         Item.Odd_Header(Number, LEFT) := Dyn.D_String(Left_Text);
  4057.         Dyn.Clear(Item.Odd_Header(Number, CENTER));
  4058.         Item.Odd_Header(Number, CENTER) := Dyn.D_String(Center_Text);
  4059.         Dyn.Clear(Item.Odd_Header(Number, RIGHT));
  4060.         Item.Odd_Header(Number, RIGHT) := Dyn.D_String(Right_Text);
  4061.       when All_Pages =>
  4062.         Dyn.Clear(Item.Even_Header(Number, LEFT));
  4063.         Item.Even_Header(Number, LEFT) := Dyn.D_String(Left_Text);
  4064.         Dyn.Clear(Item.Even_Header(Number, CENTER));
  4065.         Item.Even_Header(Number, CENTER) := Dyn.D_String(Center_Text);
  4066.         Dyn.Clear(Item.Even_Header(Number, RIGHT));
  4067.         Item.Even_Header(Number, RIGHT) := Dyn.D_String(Right_Text);
  4068.         Dyn.Clear(Item.Odd_Header(Number, LEFT));
  4069.         Item.Odd_Header(Number, LEFT) := Dyn.D_String(Left_Text);
  4070.         Dyn.Clear(Item.Odd_Header(Number, CENTER));
  4071.         Item.Odd_Header(Number, CENTER) := Dyn.D_String(Center_Text);
  4072.         Dyn.Clear(Item.Odd_Header(Number, RIGHT));
  4073.         Item.Odd_Header(Number, RIGHT) := Dyn.D_String(Right_Text);
  4074.     end case;
  4075.  
  4076.   exception
  4077.     when others =>
  4078.       Error_Log.Write_Error(Error_Internal_Set_Header_Line);
  4079.  
  4080.   end Set_Header_Line;
  4081.  
  4082.   -- ..................................
  4083.   -- .                                .
  4084.   -- .  Set_Page_Number_Id            .  BODY
  4085.   -- .                                .
  4086.   -- ..................................
  4087.   procedure Set_Page_Number_Id
  4088.     ( Item           : in File;
  4089.       To             : in CHARACTER ) is
  4090.  
  4091.   --| Notes (none)
  4092.  
  4093.   begin -- Set_Page_Number_Id
  4094.  
  4095.     if not Item.Output_Is_Open then
  4096.       raise File_Not_Open;
  4097.     end if;
  4098.     Item.Page_Number_Id := To;
  4099.  
  4100.   end Set_Page_Number_Id;
  4101.  
  4102.   -- ..................................
  4103.   -- .                                .
  4104.   -- .  Set_Page_Number_Format        .  BODY
  4105.   -- .                                .
  4106.   -- ..................................
  4107.   procedure Set_Page_Number_Format
  4108.     ( Item           : in File;
  4109.       To             : in Numeric_Format ) is
  4110.  
  4111.   --| Notes (none)
  4112.  
  4113.   begin -- Set_Page_Number_Format
  4114.  
  4115.     if not Item.Output_Is_Open then
  4116.       raise File_Not_Open;
  4117.     end if;
  4118.     Item.Pn_Format := To;
  4119.  
  4120.   end Set_Page_Number_Format;
  4121.  
  4122.   -- ..................................
  4123.   -- .                                .
  4124.   -- .  Page_Number_Format            .  BODY
  4125.   -- .                                .
  4126.   -- ..................................
  4127.   function Page_Number_Format
  4128.     ( Item           : in FILE )
  4129.     return NUMERIC_FORMAT is
  4130.  
  4131.   --| Notes (none)
  4132.  
  4133.   begin -- Page_Number_Format
  4134.  
  4135.     if not Item.Output_Is_Open then
  4136.       raise File_Not_Open;
  4137.     end if;
  4138.     return Item.Pn_Format;
  4139.  
  4140.   end Page_Number_Format;
  4141.  
  4142. end Formatted_Output_File;
  4143. --::::::::::
  4144. --idx_body.a
  4145. --::::::::::
  4146. -- **********************************
  4147. -- *                                *
  4148. -- *  Index                         *  BODY
  4149. -- *                                *
  4150. -- **********************************
  4151. with Command_Symbols;
  4152. with Error_Log;
  4153. with Output_File;
  4154. package body Index is
  4155.  
  4156. --| Notes (none)
  4157. --|
  4158. --| Modifications
  4159. --| 08/16/89  Rick Conn    Initial Version
  4160.  
  4161.   File_Id
  4162.     : Output_File.File_Type;
  4163.  
  4164.   Is_Open
  4165.     : BOOLEAN
  4166.       := false;
  4167.  
  4168.   Line_Length
  4169.     : NATURAL;
  4170.  
  4171.   use Command_Symbols;
  4172.  
  4173.   -- ..................................
  4174.   -- .                                .
  4175.   -- .  Create                        .  BODY
  4176.   -- .                                .
  4177.   -- ..................................
  4178.   procedure Create
  4179.     ( File_Name      : in STRING;
  4180.       Line_Width     : in NATURAL;
  4181.       Text_Line_Width : in NATURAL;
  4182.       Text_Line_Count : in NATURAL ) is
  4183.  
  4184.   --| Notes (none)
  4185.  
  4186.   begin -- Create
  4187.  
  4188.     Output_File.Create(File_Id, File_Name);
  4189.     Is_Open        := true;
  4190.     Line_Length    := Line_Width;
  4191.     Output_File.Put_Line(File_Id, NATURAL'Image(Text_Line_Width));
  4192.     Output_File.Put_Line(File_Id, NATURAL'Image(Text_Line_Count));
  4193.  
  4194.   exception -- Create
  4195.  
  4196.     when others =>
  4197.       raise Create_Error;
  4198.  
  4199.   end Create;
  4200.  
  4201.   -- ..................................
  4202.   -- .                                .
  4203.   -- .  Add_Entry                     .  BODY
  4204.   -- .                                .
  4205.   -- ..................................
  4206.   procedure Add_Entry
  4207.     ( Text           : in STRING;
  4208.       Page_Number    : in STRING ) is
  4209.  
  4210.   --| Notes (none)
  4211.  
  4212.     Line
  4213.       : STRING (1 .. Line_Length)
  4214.         := (others         => ' ');
  4215.  
  4216.     Last
  4217.       : NATURAL;
  4218.  
  4219.     Limit
  4220.       : NATURAL;
  4221.  
  4222.   begin -- Add_Entry
  4223.  
  4224.     if not Is_Open then
  4225.  
  4226.       raise Index_File_Not_Open;
  4227.  
  4228.     else
  4229.  
  4230.       if Text'Length + Page_Number'Length > Line_Length then
  4231.         Error_Log.Write_Warning(Warning_Index_Line_Truncation);
  4232.       end if;
  4233.       if Text'Length > Line_Length then
  4234.         Last           := Text'First + Line_Length - 1;
  4235.         Limit          := Line_Length;
  4236.       else
  4237.         Last           := Text'Last;
  4238.         Limit          := Text'Length;
  4239.       end if;
  4240.       Line(1 .. Limit) := Text(Text'First .. Last);
  4241.       if Page_Number'Length > Line_Length then
  4242.         Last           := Page_Number'First + Line_Length - 1;
  4243.         Limit          := 1;
  4244.       else
  4245.         Last           := Page_Number'Last;
  4246.         Limit          := Line_Length - Page_Number'Length + 1;
  4247.       end if;
  4248.       Line(Limit .. Line_Length) := Page_Number(Text'First .. Last);
  4249.       Output_File.Put_Line(File_Id, Line);
  4250.  
  4251.     end if;
  4252.  
  4253.   exception
  4254.     when others =>
  4255.       Error_Log.Write_Error(Error_Internal_Add_Index_Entry);
  4256.  
  4257.   end Add_Entry;
  4258.  
  4259.   -- ..................................
  4260.   -- .                                .
  4261.   -- .  Close                         .  BODY
  4262.   -- .                                .
  4263.   -- ..................................
  4264.   procedure Close is
  4265.  
  4266.   --| Notes (none)
  4267.  
  4268.   begin -- Close
  4269.  
  4270.     if Is_Open then
  4271.       Output_File.Close(File_Id);
  4272.     end if;
  4273.  
  4274.   end Close;
  4275.  
  4276. end Index;
  4277. --::::::::::
  4278. --in_body.a
  4279. --::::::::::
  4280. -- **********************************
  4281. -- *                                *
  4282. -- *  Input_File                    *  BODY
  4283. -- *                                *
  4284. -- **********************************
  4285. with Text_IO;
  4286. package body Input_File is
  4287.  
  4288. --| Notes (none)
  4289. --|
  4290. --| Modifications
  4291. --| 08/16/89  Rick Conn    Initial Version
  4292.  
  4293.   type FILE_OBJECT is
  4294.     record
  4295.       Is_Open        : BOOLEAN      := false;
  4296.       File           : Text_IO.File_Type;
  4297.     end record;
  4298.  
  4299.   -- ..................................
  4300.   -- .                                .
  4301.   -- .  Open                          .  BODY
  4302.   -- .                                .
  4303.   -- ..................................
  4304.  
  4305.   procedure Open
  4306.     ( Id             : in out File_Type;
  4307.       File_Name      : in STRING ) is
  4308.  
  4309.   --| Notes (none)
  4310.  
  4311.   begin -- Open
  4312.  
  4313.     Id             := new FILE_OBJECT;
  4314.     Text_IO.Open(Id.File, Text_IO.In_File, File_Name);
  4315.     Id.Is_Open     := true;
  4316.  
  4317.   exception -- Open -- Open
  4318.     when others =>
  4319.       raise Cannot_Open_Input_File;
  4320.  
  4321.   end Open;
  4322.  
  4323.   -- ..................................
  4324.   -- .                                .
  4325.   -- .  Get_Line                      .  BODY
  4326.   -- .                                .
  4327.   -- ..................................
  4328.   procedure Get_Line
  4329.     ( Id             : in out File_Type;
  4330.       Item           : out STRING;
  4331.       Last           : out NATURAL ) is
  4332.  
  4333.   --| Notes (none)
  4334.  
  4335.   begin -- Get_Line
  4336.  
  4337.     if Id.Is_Open then
  4338.       Text_IO.Get_Line(Id.File, Item, Last);
  4339.     end if;
  4340.  
  4341.   exception -- Get_Line -- Get_Line
  4342.     when others =>
  4343.       raise Read_Error;
  4344.  
  4345.   end Get_Line;
  4346.  
  4347.   -- ..................................
  4348.   -- .                                .
  4349.   -- .  End_Of_File                   .  BODY
  4350.   -- .                                .
  4351.   -- ..................................
  4352.   function End_Of_File
  4353.     ( Id             : in File_Type )
  4354.       return BOOLEAN is
  4355.  
  4356.   --| Notes (none)
  4357.  
  4358.   begin -- End_Of_File
  4359.  
  4360.     if Id.Is_Open then
  4361.       return Text_IO.End_Of_File(Id.File);
  4362.     end if;
  4363.  
  4364.   exception -- End_Of_File -- End_Of_File
  4365.     when others =>
  4366.       raise Read_Error;
  4367.  
  4368.   end End_Of_File;
  4369.  
  4370.   -- ..................................
  4371.   -- .                                .
  4372.   -- .  Close                         .  BODY
  4373.   -- .                                .
  4374.   -- ..................................
  4375.   procedure Close
  4376.     ( Id             : in out File_Type ) is
  4377.  
  4378.   --| Notes (none)
  4379.  
  4380.   begin -- Close
  4381.  
  4382.     if Id.Is_Open then
  4383.       Text_IO.Close(Id.File);
  4384.     end if;
  4385.  
  4386.   end Close;
  4387.  
  4388. end Input_File;
  4389. --::::::::::
  4390. --mac_body.a
  4391. --::::::::::
  4392. -- **********************************
  4393. -- *                                *
  4394. -- *  Macro                         *  BODY
  4395. -- *                                *
  4396. -- **********************************
  4397. with Command_Symbols;
  4398. with Dyn;
  4399. with Error_Log;
  4400. with Variable;
  4401. package body Macro is
  4402.  
  4403. --| Notes (none)
  4404. --|
  4405. --| Modifications
  4406. --| 08/16/89  Rick Conn    Initial Version
  4407. --| 02/26/90  Rick Conn    Init dummy ($n) parameters to null, not space
  4408.  
  4409.   Macro_Name_String_Length
  4410.     : constant
  4411.       := 20;
  4412.  
  4413.   subtype MACRO_NAME_STRING is
  4414.     STRING (1 .. Macro_Name_String_Length);
  4415.  
  4416.   type MACRO_LINE;
  4417.   type MACRO_LINE_POINTER is
  4418.     access MACRO_LINE;
  4419.  
  4420.   type MACRO_LINE is
  4421.     record
  4422.       Text           : Dyn.Dyn_String;
  4423.       Next           : MACRO_LINE_POINTER;
  4424.     end record;
  4425.  
  4426.   type MODE is
  4427.     ( CREATE_MACRO, OPEN_MACRO, INACTIVE );
  4428.  
  4429.   type MACRO_DEFINITION is
  4430.     record
  4431.       Macro_Name     : MACRO_NAME_STRING;
  4432.       Status         : MODE         := INACTIVE;
  4433.       First_Line     : MACRO_LINE_POINTER := null;
  4434.       Next_Line      : MACRO_LINE_POINTER := null;
  4435.       Last_Line      : MACRO_LINE_POINTER := null;
  4436.       Next           : Macro_Id     := null;
  4437.     end record;
  4438.  
  4439.   First_Macro
  4440.     : Macro_Id
  4441.       := null;
  4442.  
  4443.   use Command_Symbols;
  4444.  
  4445.   -- ..................................
  4446.   -- .                                .
  4447.   -- .  Locate                        .  SPEC & BODY
  4448.   -- .                                .
  4449.   -- ..................................
  4450.  
  4451.   function Locate
  4452.     ( Macro_Name     : in MACRO_NAME_STRING )
  4453.       return Macro_Id is
  4454.  
  4455.   --| Purpose
  4456.   --| Locate is internal to the package Macro (as opposed to the
  4457.   --| other Locate which returns a MACRO_STATUS, which is exported).
  4458.   --| This Locate performs the same function as the other but
  4459.   --| returns the MACRO_ID of the located macro.  If the macro named
  4460.   --| Macro_Name is not found, the value NULL is returned.
  4461.   --|
  4462.   --| Exceptions (none)
  4463.   --| Notes (none)
  4464.  
  4465.     Rover
  4466.       : Macro_Id
  4467.         := First_Macro;
  4468.  
  4469.   begin -- Locate
  4470.  
  4471.     while Rover /= null loop
  4472.       exit when Rover.Macro_Name = Macro_Name;
  4473.       Rover          := Rover.Next;
  4474.     end loop;
  4475.  
  4476.     return Rover;
  4477.  
  4478.   end Locate;
  4479.  
  4480.   -- ..................................
  4481.   -- .                                .
  4482.   -- .  Convert                       .  SPEC & BODY
  4483.   -- .                                .
  4484.   -- ..................................
  4485.   function Convert
  4486.     ( Macro_Name     : in STRING )
  4487.       return MACRO_NAME_STRING is
  4488.  
  4489.   --| Purpose
  4490.   --| Convert is internal to the package Macro.
  4491.   --| It converts the passed string to a MACRO_NAME_STRING.
  4492.   --|
  4493.   --| Exceptions (none)
  4494.   --| Notes (none)
  4495.  
  4496.     Res_Start
  4497.       : constant NATURAL
  4498.         := Macro_Name'First;
  4499.  
  4500.     Res_End
  4501.       : constant NATURAL
  4502.         := Res_Start + Macro_Name_String_Length - 1;
  4503.  
  4504.     Result
  4505.       : MACRO_NAME_STRING
  4506.         := (others         => ' ');
  4507.  
  4508.   begin -- Convert
  4509.  
  4510.     if Macro_Name'Length <= Macro_Name_String_Length then
  4511.       Result(1 .. Macro_Name'Length) := Macro_Name;
  4512.     else
  4513.       Result         := Macro_Name(Res_Start .. Res_End);
  4514.     end if;
  4515.     return Result;
  4516.  
  4517.   end Convert;
  4518.  
  4519.   -- ..................................
  4520.   -- .                                .
  4521.   -- .  Create                        .  BODY
  4522.   -- .                                .
  4523.   -- ..................................
  4524.   procedure Create
  4525.     ( Macro_Name     : in STRING;
  4526.       Id             : in out Macro_Id;
  4527.       Status         : out Macro_Status ) is
  4528.  
  4529.   --| Notes (none)
  4530.  
  4531.     Fill_String
  4532.       : constant MACRO_NAME_STRING
  4533.         := (others         => ' ');
  4534.  
  4535.     Limit
  4536.       : INTEGER
  4537.         := Macro_Name_String_Length - Macro_Name'Length;
  4538.  
  4539.   begin -- Create
  4540.  
  4541.     Id             := new MACRO_DEFINITION;
  4542.     Id.Macro_Name  := Convert(Macro_Name);
  4543.     Id.Status      := CREATE_MACRO;
  4544.     Status         := Ok;
  4545.  
  4546.   exception -- Create -- Create
  4547.     when others =>
  4548.       Status         := Not_Ok;
  4549.  
  4550.   end Create;
  4551.  
  4552.   -- ..................................
  4553.   -- .                                .
  4554.   -- .  Write                         .  BODY
  4555.   -- .                                .
  4556.   -- ..................................
  4557.   procedure Write
  4558.     ( Id             : in out Macro_Id;
  4559.       Line           : in STRING ) is
  4560.  
  4561.   --| Notes (none)
  4562.  
  4563.   begin -- Write
  4564.  
  4565.     if Id.Status /= CREATE_MACRO then
  4566.       raise Macro_Not_In_Add_Mode;
  4567.     end if;
  4568.     if Id.Last_Line = null then
  4569.       Id.Last_Line   := new MACRO_LINE;
  4570.       Id.First_Line  := Id.Last_Line;
  4571.     else
  4572.       Id.Last_Line.Next := new MACRO_LINE;
  4573.       Id.Last_Line   := Id.Last_Line.Next;
  4574.     end if;
  4575.     Id.Last_Line.Text := Dyn.D_String(Line);
  4576.  
  4577.   exception
  4578.     when others =>
  4579.       Error_Log.Write_Error(Error_Internal_Macro_Write);
  4580.  
  4581.   end Write;
  4582.  
  4583.   -- ..................................
  4584.   -- .                                .
  4585.   -- .  Open                          .  BODY
  4586.   -- .                                .
  4587.   -- ..................................
  4588.   procedure Open
  4589.     ( Macro_Name     : in STRING;
  4590.       Id             : out Macro_Id;
  4591.       Status         : out Macro_Status ) is
  4592.  
  4593.   --| Notes (none)
  4594.  
  4595.     Search_Result
  4596.       : Macro_Id;
  4597.  
  4598.   begin -- Open
  4599.  
  4600.     Search_Result  := Locate(Convert(Macro_Name));
  4601.     if Search_Result = null then
  4602.       Status         := Not_Ok;
  4603.     else
  4604.       Status         := Ok;
  4605.     end if;
  4606.  
  4607.     Id             := Search_Result;
  4608.  
  4609.     if Search_Result /= null then
  4610.       Search_Result.Status := OPEN_MACRO;
  4611.       Search_Result.Next_Line := Search_Result.First_Line;
  4612.     end if;
  4613.  
  4614.   end Open;
  4615.  
  4616.   -- ..................................
  4617.   -- .                                .
  4618.   -- .  Is_Empty                      .  BODY
  4619.   -- .                                .
  4620.   -- ..................................
  4621.   function Is_Empty
  4622.     ( Id             : in Macro_Id )
  4623.       return BOOLEAN is
  4624.  
  4625.   --| Notes (none)
  4626.  
  4627.   begin -- Is_Empty
  4628.  
  4629.     if Id.Status /= OPEN_MACRO then
  4630.       raise Macro_Not_Open;
  4631.     end if;
  4632.     return Id.Next_Line = null;
  4633.  
  4634.   end Is_Empty;
  4635.  
  4636.   -- ..................................
  4637.   -- .                                .
  4638.   -- .  Read                          .  BODY
  4639.   -- .                                .
  4640.   -- ..................................
  4641.   procedure Read
  4642.     ( Id             : in out Macro_Id;
  4643.       Item           : out STRING;
  4644.       Last           : out NATURAL ) is
  4645.  
  4646.   --| Notes (none)
  4647.  
  4648.     Local_Last
  4649.       : NATURAL;
  4650.  
  4651.   begin -- Read
  4652.  
  4653.     if Id.Status /= OPEN_MACRO then
  4654.       raise Macro_Not_Open;
  4655.     end if;
  4656.     if Id.Next_Line = null then
  4657.       Item(Item'First .. Item'First) := " ";
  4658.       Last           := Item'First - 1;
  4659.     else
  4660.       Local_Last     := Dyn.Length(Id.Next_Line.Text) + Item'First - 1;
  4661.       Item(Item'First .. Local_Last) := Dyn.Str(Id.Next_Line.Text);
  4662.       Last           := Local_Last;
  4663.       Id.Next_Line   := Id.Next_Line.Next;
  4664.     end if;
  4665.  
  4666.   end Read;
  4667.  
  4668.   -- ..................................
  4669.   -- .                                .
  4670.   -- .  Close                         .  BODY
  4671.   -- .                                .
  4672.   -- ..................................
  4673.   procedure Close
  4674.     ( Id             : in out Macro_Id ) is
  4675.  
  4676.   --| Notes
  4677.   --| If the Id is in Create mode, Close adds it to the front of the
  4678.   --| main list.
  4679.  
  4680.   begin -- Close
  4681.  
  4682.     if Id.Status = CREATE_MACRO then
  4683.       if First_Macro = null then
  4684.         First_Macro    := Id;
  4685.       else
  4686.         Id.Next        := First_Macro;           -- add to front of list
  4687.         First_Macro    := Id;
  4688.       end if;
  4689.     end if;
  4690.     Id.Status      := INACTIVE;
  4691.  
  4692.   end Close;
  4693.  
  4694.   -- ..................................
  4695.   -- .                                .
  4696.   -- .  Locate                        .  BODY
  4697.   -- .                                .
  4698.   -- ..................................
  4699.   function Locate
  4700.     ( Macro_Name     : in STRING )
  4701.       return Macro_Status is
  4702.  
  4703.   --| Notes (none)
  4704.  
  4705.     Result
  4706.       : Macro_Id;
  4707.  
  4708.   begin -- Locate
  4709.  
  4710.     Result         := Locate(Convert(Macro_Name));
  4711.     if Result /= null then
  4712.       return Ok;
  4713.     else
  4714.       return Not_Ok;
  4715.     end if;
  4716.  
  4717.   end Locate;
  4718.  
  4719.   -- ..................................
  4720.   -- .                                .
  4721.   -- .  Define_Parameters             .  BODY
  4722.   -- .                                .
  4723.   -- ..................................
  4724.   procedure Define_Parameters
  4725.     ( Macro_Name     : in STRING;
  4726.       Parameters     : in STRING ) is
  4727.  
  4728.   --| Notes (none)
  4729.  
  4730.     Start
  4731.       : NATURAL;
  4732.  
  4733.     Stop
  4734.       : NATURAL;
  4735.  
  4736.     Number
  4737.       : STRING (1 .. 1)
  4738.         := "1";
  4739.  
  4740.     type PARSE_STATE is
  4741.       ( IN_TEXT, IN_LAST, NOT_IN_TEXT );
  4742.  
  4743.     State
  4744.       : PARSE_STATE
  4745.         := NOT_IN_TEXT;
  4746.  
  4747.   begin -- Define_Parameters
  4748.  
  4749.     Variable.Set_Var("0", Macro_Name);
  4750.     for I in Parameters'range loop
  4751.       case State is
  4752.         when NOT_IN_TEXT =>
  4753.           if Parameters(I) > ' ' then
  4754.             if Number(1) = '9' then
  4755.               State          := IN_LAST;
  4756.             else
  4757.               State          := IN_TEXT;
  4758.             end if;
  4759.             Start          := I;
  4760.           end if;
  4761.         when IN_LAST =>
  4762.           null;
  4763.         when IN_TEXT =>
  4764.           if Parameters(I) <= ' ' then
  4765.             Stop           := I - 1;
  4766.             Variable.Set_Var(Number, Parameters(Start .. Stop));
  4767.             Number(1)      := CHARACTER'Succ(Number(1));
  4768.             State          := NOT_IN_TEXT;
  4769.           end if;
  4770.       end case;
  4771.     end loop;
  4772.     if (State = IN_LAST) or (State = IN_TEXT) then
  4773.       Variable.Set_Var(Number, Parameters(Start .. Parameters'Last));
  4774.     else
  4775.       Variable.Set_Var(Number, " ");
  4776.     end if;
  4777.     while Number(1) /= '9' loop
  4778.       Number(1)      := CHARACTER'Succ(Number(1));
  4779.       Variable.Set_Var(Number, " ");
  4780.     end loop;
  4781.  
  4782.   exception
  4783.     when others =>
  4784.       Error_Log.Write_Error(Error_Internal_Macro_Define);
  4785.  
  4786.   end Define_Parameters;
  4787.  
  4788. end Macro;
  4789. --::::::::::
  4790. --out_body.a
  4791. --::::::::::
  4792. -- **********************************
  4793. -- *                                *
  4794. -- *  Output_File                   *  BODY
  4795. -- *                                *
  4796. -- **********************************
  4797. with Text_IO;
  4798. package body Output_File is
  4799.  
  4800. --| Notes (none)
  4801. --|
  4802. --| Modifications
  4803. --| 08/16/89  Rick Conn    Initial Version
  4804. --| 02/26/90  Rick Conn    Fix bug in Already_Exists test
  4805.  
  4806.   type FILE_OBJECT is
  4807.     record
  4808.       File           : Text_IO.File_Type;
  4809.       Is_Open        : BOOLEAN      := false;
  4810.       Is_Output_Enabled : BOOLEAN   := true;
  4811.     end record;
  4812.  
  4813.   -- ..................................
  4814.   -- .                                .
  4815.   -- .  Already_Exists                .  BODY
  4816.   -- .                                .
  4817.   -- ..................................
  4818.   function Already_Exists
  4819.     ( File_Name      : in STRING )
  4820.     return BOOLEAN is
  4821.  
  4822.   --| Notes (none)
  4823.  
  4824.     File
  4825.       : Text_IO.File_Type;
  4826.  
  4827.     Result
  4828.       : BOOLEAN
  4829.         := true;
  4830.  
  4831.   begin -- Already_Exists
  4832.  
  4833.     begin
  4834.       Text_IO.Open(File, Text_IO.In_File, File_Name);
  4835.       Text_IO.Close(File);
  4836.     exception
  4837.       when others =>
  4838.         Result := false;
  4839.     end;
  4840.     return Result;
  4841.  
  4842.   end Already_Exists;
  4843.  
  4844.   -- ..................................
  4845.   -- .                                .
  4846.   -- .  Delete                        .  BODY
  4847.   -- .                                .
  4848.   -- ..................................
  4849.   function Delete
  4850.     ( File_Name      : in STRING )
  4851.     return BOOLEAN is
  4852.  
  4853.   --| Notes (none)
  4854.  
  4855.     File
  4856.       : Text_IO.File_Type;
  4857.  
  4858.     Result
  4859.       : BOOLEAN
  4860.         := true;
  4861.  
  4862.   begin -- Delete
  4863.  
  4864.     begin
  4865.       if Already_Exists(File_Name) then
  4866.         Text_IO.Open(File, Text_IO.Out_File, File_Name);
  4867.         Text_IO.Delete(File);
  4868.       end if;
  4869.  
  4870.     exception
  4871.       when others =>
  4872.         Result := false;
  4873.     end;
  4874.     return Result;
  4875.  
  4876.   end Delete;
  4877.  
  4878.   -- ..................................
  4879.   -- .                                .
  4880.   -- .  Create                        .  BODY
  4881.   -- .                                .
  4882.   -- ..................................
  4883.   procedure Create
  4884.     ( Id             : in out File_Type;
  4885.       File_Name      : in STRING ) is
  4886.  
  4887.   --| Notes (none)
  4888.  
  4889.   begin -- Create
  4890.  
  4891.     Id             := new FILE_OBJECT;
  4892.     Text_IO.Create(Id.File, Text_IO.Out_File, File_Name);
  4893.     Id.Is_Open     := true;
  4894.     Id.Is_Output_Enabled := true;
  4895.  
  4896.   exception -- Create -- Create
  4897.     when others =>
  4898.       raise Cannot_Create_Output_File;
  4899.  
  4900.   end Create;
  4901.  
  4902.   -- ..................................
  4903.   -- .                                .
  4904.   -- .  Put                           .  BODY
  4905.   -- .                                .
  4906.   -- ..................................
  4907.   procedure Put
  4908.     ( Id             : in out File_Type;
  4909.       Item           : in CHARACTER ) is
  4910.  
  4911.   --| Notes (none)
  4912.  
  4913.   begin -- Put
  4914.  
  4915.     if Id.Is_Open and Id.Is_Output_Enabled then
  4916.       Text_IO.Put(Id.File, Item);
  4917.     end if;
  4918.  
  4919.   exception -- Put -- Put
  4920.     when others =>
  4921.       raise Write_Error;
  4922.  
  4923.   end Put;
  4924.  
  4925.   -- ..................................
  4926.   -- .                                .
  4927.   -- .  Put                           .  BODY
  4928.   -- .                                .
  4929.   -- ..................................
  4930.   procedure Put
  4931.     ( Id             : in out File_Type;
  4932.       Item           : in STRING ) is
  4933.  
  4934.   --| Notes (none)
  4935.  
  4936.   begin -- Put
  4937.  
  4938.     if Id.Is_Open and Id.Is_Output_Enabled then
  4939.       Text_IO.Put(Id.File, Item);
  4940.     end if;
  4941.  
  4942.   exception -- Put -- Put
  4943.     when others =>
  4944.       raise Write_Error;
  4945.  
  4946.   end Put;
  4947.  
  4948.   -- ..................................
  4949.   -- .                                .
  4950.   -- .  Put_Line                      .  BODY
  4951.   -- .                                .
  4952.   -- ..................................
  4953.   procedure Put_Line
  4954.     ( Id             : in out File_Type;
  4955.       Item           : in STRING ) is
  4956.  
  4957.   --| Notes (none)
  4958.  
  4959.   begin -- Put_Line
  4960.  
  4961.     if Id.Is_Open and Id.Is_Output_Enabled then
  4962.       Text_IO.Put_Line(Id.File, Item);
  4963.     end if;
  4964.  
  4965.   exception -- Put_Line -- Put_Line
  4966.     when others =>
  4967.       raise Write_Error;
  4968.  
  4969.   end Put_Line;
  4970.  
  4971.   -- ..................................
  4972.   -- .                                .
  4973.   -- .  New_Line                      .  BODY
  4974.   -- .                                .
  4975.   -- ..................................
  4976.   procedure New_Line
  4977.     ( Id             : in out File_Type ) is
  4978.  
  4979.   --| Notes (none)
  4980.  
  4981.   begin -- New_Line
  4982.  
  4983.     if Id.Is_Open and Id.Is_Output_Enabled then
  4984.       Text_IO.New_Line(Id.File);
  4985.     end if;
  4986.  
  4987.   exception -- New_Line -- New_Line
  4988.     when others =>
  4989.       raise Write_Error;
  4990.  
  4991.   end New_Line;
  4992.  
  4993.   -- ..................................
  4994.   -- .                                .
  4995.   -- .  New_Page                      .  BODY
  4996.   -- .                                .
  4997.   -- ..................................
  4998.   procedure New_Page
  4999.     ( Id             : in out File_Type ) is
  5000.  
  5001.   --| Notes (none)
  5002.  
  5003.   begin -- New_Page
  5004.  
  5005.     if Id.Is_Open and Id.Is_Output_Enabled then
  5006.       Text_IO.New_Page(Id.File);
  5007.     end if;
  5008.  
  5009.   exception -- New_Page -- New_Page
  5010.     when others =>
  5011.       raise Write_Error;
  5012.  
  5013.   end New_Page;
  5014.  
  5015.   -- ..................................
  5016.   -- .                                .
  5017.   -- .  Enable_Output                 .  BODY
  5018.   -- .                                .
  5019.   -- ..................................
  5020.   procedure Enable_Output
  5021.     ( Id             : in out File_Type ) is
  5022.  
  5023.   --| Notes (none)
  5024.  
  5025.   begin -- Enable_Output
  5026.  
  5027.     Id.Is_Output_Enabled := true;
  5028.  
  5029.   end Enable_Output;
  5030.  
  5031.   -- ..................................
  5032.   -- .                                .
  5033.   -- .  Disable_Output                .  BODY
  5034.   -- .                                .
  5035.   -- ..................................
  5036.   procedure Disable_Output
  5037.     ( Id             : in out File_Type ) is
  5038.  
  5039.   --| Notes (none)
  5040.  
  5041.   begin -- Disable_Output
  5042.  
  5043.     Id.Is_Output_Enabled := false;
  5044.  
  5045.   end Disable_Output;
  5046.  
  5047.   -- ..................................
  5048.   -- .                                .
  5049.   -- .  Close                         .  BODY
  5050.   -- .                                .
  5051.   -- ..................................
  5052.   procedure Close
  5053.     ( Id             : in out File_Type ) is
  5054.  
  5055.   --| Notes (none)
  5056.  
  5057.   begin -- Close
  5058.  
  5059.     if Id.Is_Open then
  5060.       Text_IO.Close(Id.File);
  5061.     end if;
  5062.  
  5063.   end Close;
  5064.  
  5065. end Output_File;
  5066. --::::::::::
  5067. --var_body.a
  5068. --::::::::::
  5069. -- **********************************
  5070. -- *                                *
  5071. -- *  Variable                      *  BODY
  5072. -- *                                *
  5073. -- **********************************
  5074. with Command_Symbols;
  5075. with Dyn;
  5076. with Error_Log;
  5077. package body Variable is
  5078.  
  5079. --| Notes (none)
  5080. --|
  5081. --| Modifications
  5082. --| 08/16/89  Rick Conn    Initial Version
  5083.  
  5084.   Ap_Flag
  5085.     : BOOLEAN
  5086.       := Default_Auto_Paragraph;
  5087.  
  5088.   Bd_Count
  5089.     : NATURAL
  5090.       := 0;
  5091.  
  5092.   Ce_Count
  5093.     : NATURAL
  5094.       := 0;
  5095.  
  5096.   Ul_Count
  5097.     : NATURAL
  5098.       := 0;
  5099.  
  5100.   Cc_Char
  5101.     : CHARACTER
  5102.       := Default_Cc;
  5103.  
  5104.   Ec_Char
  5105.     : CHARACTER
  5106.       := Default_Ec;
  5107.  
  5108.   Fc_Char
  5109.     : CHARACTER
  5110.       := Default_Fc;
  5111.  
  5112.   type NREG_ARRAY is
  5113.     array (Nreg)
  5114.       of NATURAL;
  5115.  
  5116.   Number
  5117.     : NREG_ARRAY
  5118.       := (others         => 0);
  5119.  
  5120.   Input_File_Name
  5121.     : STRING (1 .. 100);
  5122.  
  5123.   Input_File_Name_Last
  5124.     : NATURAL;
  5125.  
  5126.   File_Line_Number
  5127.     : NATURAL;
  5128.  
  5129.   Var_Name_String_Length
  5130.     : constant
  5131.       := 20;
  5132.  
  5133.   subtype VAR_NAME_STRING is
  5134.     STRING (1 .. Var_Name_String_Length);
  5135.  
  5136.   type VAR_DEFINITION;
  5137.   type VAR_LIST_POINTER is
  5138.     access VAR_DEFINITION;
  5139.  
  5140.   type VAR_DEFINITION is
  5141.     record
  5142.       Var_Name       : VAR_NAME_STRING;
  5143.       Text           : Dyn.Dyn_String;
  5144.       Next           : VAR_LIST_POINTER := null;
  5145.     end record;
  5146.  
  5147.   First_Var
  5148.     : VAR_LIST_POINTER
  5149.       := null;
  5150.  
  5151.   use Command_Symbols;
  5152.  
  5153.   -- ..................................
  5154.   -- .                                .
  5155.   -- .  Set_Auto_Paragraph            .  BODY
  5156.   -- .                                .
  5157.   -- ..................................
  5158.  
  5159.   procedure Set_Auto_Paragraph
  5160.     ( Item           : in BOOLEAN ) is
  5161.  
  5162.   --| Notes (none)
  5163.  
  5164.   begin -- Set_Auto_Paragraph
  5165.  
  5166.     Ap_Flag        := Item;
  5167.  
  5168.   end Set_Auto_Paragraph;
  5169.  
  5170.   -- ..................................
  5171.   -- .                                .
  5172.   -- .  Is_Auto_Paragraph             .  BODY
  5173.   -- .                                .
  5174.   -- ..................................
  5175.   function Is_Auto_Paragraph
  5176.       return BOOLEAN is
  5177.  
  5178.   --| Notes (none)
  5179.  
  5180.   begin -- Is_Auto_Paragraph
  5181.  
  5182.     return Ap_Flag;
  5183.  
  5184.   end Is_Auto_Paragraph;
  5185.  
  5186.   -- ..................................
  5187.   -- .                                .
  5188.   -- .  Set_Bold_Count                .  BODY
  5189.   -- .                                .
  5190.   -- ..................................
  5191.   procedure Set_Bold_Count
  5192.     ( Value          : in NATURAL ) is
  5193.  
  5194.   --| Notes (none)
  5195.  
  5196.   begin -- Set_Bold_Count
  5197.  
  5198.     Bd_Count       := Value;
  5199.  
  5200.   end Set_Bold_Count;
  5201.  
  5202.   -- ..................................
  5203.   -- .                                .
  5204.   -- .  Bold_Count                    .  BODY
  5205.   -- .                                .
  5206.   -- ..................................
  5207.   function Bold_Count
  5208.       return NATURAL is
  5209.  
  5210.   --| Notes (none)
  5211.  
  5212.   begin -- Bold_Count
  5213.  
  5214.     return Bd_Count;
  5215.  
  5216.   end Bold_Count;
  5217.  
  5218.   -- ..................................
  5219.   -- .                                .
  5220.   -- .  Set_Center_Count              .  BODY
  5221.   -- .                                .
  5222.   -- ..................................
  5223.   procedure Set_Center_Count
  5224.     ( Value          : in NATURAL ) is
  5225.  
  5226.   --| Notes (none)
  5227.  
  5228.   begin -- Set_Center_Count
  5229.  
  5230.     Ce_Count       := Value;
  5231.  
  5232.   end Set_Center_Count;
  5233.  
  5234.   -- ..................................
  5235.   -- .                                .
  5236.   -- .  Center_Count                  .  BODY
  5237.   -- .                                .
  5238.   -- ..................................
  5239.   function Center_Count
  5240.       return NATURAL is
  5241.  
  5242.   --| Notes (none)
  5243.  
  5244.   begin -- Center_Count
  5245.  
  5246.     return Ce_Count;
  5247.  
  5248.   end Center_Count;
  5249.  
  5250.   -- ..................................
  5251.   -- .                                .
  5252.   -- .  Set_Underline_Count           .  BODY
  5253.   -- .                                .
  5254.   -- ..................................
  5255.   procedure Set_Underline_Count
  5256.     ( Value          : in NATURAL ) is
  5257.  
  5258.   --| Notes (none)
  5259.  
  5260.   begin -- Set_Underline_Count
  5261.  
  5262.     Ul_Count       := Value;
  5263.  
  5264.   end Set_Underline_Count;
  5265.  
  5266.   -- ..................................
  5267.   -- .                                .
  5268.   -- .  Underline_Count               .  BODY
  5269.   -- .                                .
  5270.   -- ..................................
  5271.   function Underline_Count
  5272.       return NATURAL is
  5273.  
  5274.   --| Notes (none)
  5275.  
  5276.   begin -- Underline_Count
  5277.  
  5278.     return Ul_Count;
  5279.  
  5280.   end Underline_Count;
  5281.  
  5282.   -- ..................................
  5283.   -- .                                .
  5284.   -- .  Set_Cc                        .  BODY
  5285.   -- .                                .
  5286.   -- ..................................
  5287.   procedure Set_Cc
  5288.     ( Item           : in CHARACTER ) is
  5289.  
  5290.   --| Notes (none)
  5291.  
  5292.   begin -- Set_Cc
  5293.  
  5294.     Cc_Char        := Item;
  5295.  
  5296.   end Set_Cc;
  5297.  
  5298.   -- ..................................
  5299.   -- .                                .
  5300.   -- .  Cc                            .  BODY
  5301.   -- .                                .
  5302.   -- ..................................
  5303.   function Cc
  5304.       return CHARACTER is
  5305.  
  5306.   --| Notes (none)
  5307.  
  5308.   begin -- Cc
  5309.  
  5310.     return Cc_Char;
  5311.  
  5312.   end Cc;
  5313.  
  5314.   -- ..................................
  5315.   -- .                                .
  5316.   -- .  Set_Ec                        .  BODY
  5317.   -- .                                .
  5318.   -- ..................................
  5319.   procedure Set_Ec
  5320.     ( Item           : in CHARACTER ) is
  5321.  
  5322.   --| Notes (none)
  5323.  
  5324.   begin -- Set_Ec
  5325.  
  5326.     Ec_Char        := Item;
  5327.  
  5328.   end Set_Ec;
  5329.  
  5330.   -- ..................................
  5331.   -- .                                .
  5332.   -- .  Ec                            .  BODY
  5333.   -- .                                .
  5334.   -- ..................................
  5335.   function Ec
  5336.       return CHARACTER is
  5337.  
  5338.   --| Notes (none)
  5339.  
  5340.   begin -- Ec
  5341.  
  5342.     return Ec_Char;
  5343.  
  5344.   end Ec;
  5345.  
  5346.   -- ..................................
  5347.   -- .                                .
  5348.   -- .  Set_Fc                        .  BODY
  5349.   -- .                                .
  5350.   -- ..................................
  5351.   procedure Set_Fc
  5352.     ( Item           : in CHARACTER ) is
  5353.  
  5354.   --| Notes (none)
  5355.  
  5356.   begin -- Set_Fc
  5357.  
  5358.     Fc_Char        := Item;
  5359.  
  5360.   end Set_Fc;
  5361.  
  5362.   -- ..................................
  5363.   -- .                                .
  5364.   -- .  Fc                            .  BODY
  5365.   -- .                                .
  5366.   -- ..................................
  5367.   function Fc
  5368.       return CHARACTER is
  5369.  
  5370.   --| Notes (none)
  5371.  
  5372.   begin -- Fc
  5373.  
  5374.     return Fc_Char;
  5375.  
  5376.   end Fc;
  5377.  
  5378.   -- ..................................
  5379.   -- .                                .
  5380.   -- .  Set_Nr                        .  BODY
  5381.   -- .                                .
  5382.   -- ..................................
  5383.   procedure Set_Nr
  5384.     ( Item           : in Nreg;
  5385.       Value          : in NATURAL ) is
  5386.  
  5387.   --| Notes (none)
  5388.  
  5389.   begin -- Set_Nr
  5390.  
  5391.     Number(Item)   := Value;
  5392.  
  5393.   end Set_Nr;
  5394.  
  5395.   -- ..................................
  5396.   -- .                                .
  5397.   -- .  Nr                            .  BODY
  5398.   -- .                                .
  5399.   -- ..................................
  5400.   function Nr
  5401.     ( Item           : in Nreg )
  5402.       return NATURAL is
  5403.  
  5404.   --| Notes (none)
  5405.  
  5406.   begin -- Nr
  5407.  
  5408.     return Number(Item);
  5409.  
  5410.   end Nr;
  5411.  
  5412.   -- ..................................
  5413.   -- .                                .
  5414.   -- .  Nr                            .  BODY
  5415.   -- .                                .
  5416.   -- ..................................
  5417.   procedure Nr
  5418.     ( Item           : in Nreg;
  5419.       Value          : out STRING;
  5420.       Last           : out NATURAL ) is
  5421.  
  5422.   --| Notes (none)
  5423.  
  5424.     Buffer
  5425.       : STRING (1 .. 20);
  5426.  
  5427.     Length
  5428.       : NATURAL;
  5429.  
  5430.     Temp_Last
  5431.       : NATURAL;
  5432.  
  5433.     -- ..................................
  5434.     -- .                                .
  5435.     -- .  Nr.Set_Buffer                 .  SPEC & BODY
  5436.     -- .                                .
  5437.     -- ..................................
  5438.     procedure Set_Buffer
  5439.       ( Value          : in STRING ) is
  5440.  
  5441.     --| Notes (none)
  5442.  
  5443.     begin -- Set_Buffer
  5444.  
  5445.       Buffer(1 .. Value'Length) := Value;
  5446.       Length         := Value'Length;
  5447.  
  5448.     end Set_Buffer;
  5449.  
  5450.   begin -- Nr
  5451.  
  5452.     Set_Buffer(NATURAL'Image(Nr(Item)));
  5453.     Temp_Last      := Value'First + Length - 2;
  5454.     Value(Value'First .. Temp_Last) := Buffer(2 .. Length);
  5455.     Last           := Temp_Last;
  5456.  
  5457.   end Nr;
  5458.  
  5459.   -- ..................................
  5460.   -- .                                .
  5461.   -- .  Convert                       .  SPEC & BODY
  5462.   -- .                                .
  5463.   -- ..................................
  5464.   function Convert
  5465.     ( Var_Name       : in STRING )
  5466.       return VAR_NAME_STRING is
  5467.  
  5468.   --| Purpose
  5469.   --| Convert is internal to the package Variable.
  5470.   --| It converts the passed string to a VAR_NAME_STRING.
  5471.   --|
  5472.   --| Exceptions (none)
  5473.   --| Notes (none)
  5474.  
  5475.     Res_Start
  5476.       : constant NATURAL
  5477.         := Var_Name'First;
  5478.  
  5479.     Res_End
  5480.       : constant NATURAL
  5481.         := Res_Start + Var_Name_String_Length - 1;
  5482.  
  5483.     Result
  5484.       : VAR_NAME_STRING
  5485.         := (others         => ' ');
  5486.  
  5487.   begin -- Convert
  5488.  
  5489.     if Var_Name'Length <= Var_Name_String_Length then
  5490.       Result(1 .. Var_Name'Length) := Var_Name;
  5491.     else
  5492.       Result         := Var_Name(Res_Start .. Res_End);
  5493.     end if;
  5494.     return Result;
  5495.  
  5496.   end Convert;
  5497.  
  5498.   -- ..................................
  5499.   -- .                                .
  5500.   -- .  Locate                        .  SPEC & BODY
  5501.   -- .                                .
  5502.   -- ..................................
  5503.   function Locate
  5504.     ( Var_Name       : in VAR_NAME_STRING )
  5505.       return VAR_LIST_POINTER is
  5506.  
  5507.   --| Purpose
  5508.   --| Locate is internal to the package Variable.
  5509.   --| It returns a pointer to the named variable or NULL if not found.
  5510.   --|
  5511.   --| Exceptions (none)
  5512.   --| Notes (none)
  5513.  
  5514.     Rover
  5515.       : VAR_LIST_POINTER
  5516.         := First_Var;
  5517.  
  5518.   begin -- Locate
  5519.  
  5520.     while Rover /= null loop
  5521.       exit when Rover.Var_Name = Var_Name;
  5522.       Rover          := Rover.Next;
  5523.     end loop;
  5524.     return Rover;
  5525.  
  5526.   end Locate;
  5527.  
  5528.   -- ..................................
  5529.   -- .                                .
  5530.   -- .  Set_Var                       .  BODY
  5531.   -- .                                .
  5532.   -- ..................................
  5533.   procedure Set_Var
  5534.     ( Name           : in STRING;
  5535.       Value          : in STRING ) is
  5536.  
  5537.   --| Notes (none)
  5538.  
  5539.     Target
  5540.       : VAR_NAME_STRING
  5541.         := Convert(Name);
  5542.  
  5543.     Target_Pointer
  5544.       : VAR_LIST_POINTER
  5545.         := Locate(Target);
  5546.  
  5547.     Temp
  5548.       : VAR_LIST_POINTER;
  5549.  
  5550.   begin -- Set_Var
  5551.  
  5552.     if Target_Pointer = null then
  5553.       Temp           := new VAR_DEFINITION;
  5554.       Temp.Var_Name  := Target;
  5555.       Temp.Text      := Dyn.D_String(Value);
  5556.       Temp.Next      := First_Var;
  5557.       First_Var      := Temp;
  5558.     else
  5559.       Dyn.Clear(Target_Pointer.Text);
  5560.       Target_Pointer.Text := Dyn.D_String(Value);
  5561.     end if;
  5562.  
  5563.   exception
  5564.     when others =>
  5565.       Error_Log.Write_Error(Error_Internal_Set_Var);
  5566.  
  5567.   end Set_Var;
  5568.  
  5569.   -- ..................................
  5570.   -- .                                .
  5571.   -- .  Var                           .  BODY
  5572.   -- .                                .
  5573.   -- ..................................
  5574.   function Var
  5575.     ( Name           : in STRING )
  5576.       return STRING is
  5577.  
  5578.   --| Notes (none)
  5579.  
  5580.     Target
  5581.       : VAR_NAME_STRING
  5582.         := Convert(Name);
  5583.  
  5584.     Target_Pointer
  5585.       : VAR_LIST_POINTER
  5586.         := Locate(Target);
  5587.  
  5588.   begin -- Var
  5589.  
  5590.     if Target_Pointer = null then
  5591.       return "";
  5592.     else
  5593.       return Dyn.Str(Target_Pointer.Text);
  5594.     end if;
  5595.  
  5596.   end Var;
  5597.  
  5598.   -- ..................................
  5599.   -- .                                .
  5600.   -- .  Var                           .  BODY
  5601.   -- .                                .
  5602.   -- ..................................
  5603.   procedure Var
  5604.     ( Name           : in STRING;
  5605.       Value          : out STRING;
  5606.       Last           : out NATURAL ) is
  5607.  
  5608.   --| Notes (none)
  5609.  
  5610.     Target
  5611.       : VAR_NAME_STRING
  5612.         := Convert(Name);
  5613.  
  5614.     Tp
  5615.       : VAR_LIST_POINTER
  5616.         := Locate(Target);
  5617.  
  5618.     Local_Last
  5619.       : NATURAL;
  5620.  
  5621.   begin -- Var
  5622.  
  5623.     if Tp = null then
  5624.       Last           := Value'First - 1;
  5625.       Value(Value'First) := ' ';
  5626.     else
  5627.       Local_Last     := Dyn.Length(Tp.Text) + Value'First - 1;
  5628.       Value(Value'First .. Local_Last) := Dyn.Str(Tp.Text);
  5629.       Last           := Local_Last;
  5630.     end if;
  5631.  
  5632.   end Var;
  5633.  
  5634.   -- ..................................
  5635.   -- .                                .
  5636.   -- .  Set_File_Name                 .  BODY
  5637.   -- .                                .
  5638.   -- ..................................
  5639.   procedure Set_File_Name
  5640.     ( Name           : in STRING ) is
  5641.  
  5642.   --| Notes (none)
  5643.  
  5644.   begin -- Set_File_Name
  5645.  
  5646.     if Name'Length <= Input_File_Name'Length then
  5647.       Input_File_Name(1 .. Name'Length) := Name;
  5648.       Input_File_Name_Last := Name'Length;
  5649.     else
  5650.       Input_File_Name := Name(Name'First .. Name'First
  5651.           + Input_File_Name'Length - 1);
  5652.       Input_File_Name_Last := Input_File_Name'Length;
  5653.     end if;
  5654.     File_Line_Number := 0;
  5655.  
  5656.   end Set_File_Name;
  5657.  
  5658.   -- ..................................
  5659.   -- .                                .
  5660.   -- .  Get_File_Name                 .  BODY
  5661.   -- .                                .
  5662.   -- ..................................
  5663.   function Get_File_Name
  5664.       return STRING is
  5665.  
  5666.   --| Notes (none)
  5667.  
  5668.   begin -- Get_File_Name
  5669.  
  5670.     return Input_File_Name(1 .. Input_File_Name_Last);
  5671.  
  5672.   end Get_File_Name;
  5673.  
  5674.   -- ..................................
  5675.   -- .                                .
  5676.   -- .  Set_Line_Number               .  BODY
  5677.   -- .                                .
  5678.   -- ..................................
  5679.   procedure Set_Line_Number
  5680.     ( Value          : in NATURAL ) is
  5681.  
  5682.   --| Notes (none)
  5683.  
  5684.   begin -- Set_Line_Number
  5685.  
  5686.     File_Line_Number := Value;
  5687.  
  5688.   end Set_Line_Number;
  5689.  
  5690.   -- ..................................
  5691.   -- .                                .
  5692.   -- .  Increment_Line_Number         .  BODY
  5693.   -- .                                .
  5694.   -- ..................................
  5695.   procedure Increment_Line_Number is
  5696.  
  5697.   --| Notes (none)
  5698.  
  5699.   begin -- Increment_Line_Number
  5700.  
  5701.     File_Line_Number := File_Line_Number + 1;
  5702.  
  5703.   exception
  5704.     when others =>
  5705.       Error_Log.Write_Error(Error_Internal_Increment);
  5706.  
  5707.   end Increment_Line_Number;
  5708.  
  5709.   -- ..................................
  5710.   -- .                                .
  5711.   -- .  Line_Number                   .  BODY
  5712.   -- .                                .
  5713.   -- ..................................
  5714.   function Line_Number
  5715.       return NATURAL is
  5716.  
  5717.   --| Notes (none)
  5718.  
  5719.   begin -- Line_Number
  5720.  
  5721.     return File_Line_Number;
  5722.  
  5723.   end Line_Number;
  5724.  
  5725. end Variable;
  5726. --::::::::::
  5727. --wp_body.a
  5728. --::::::::::
  5729. -- **********************************
  5730. -- *                                *
  5731. -- *  Word_Processor                *  BODY
  5732. -- *                                *
  5733. -- **********************************
  5734. with Command;
  5735. with Command_Symbols;
  5736. with Error_Log;
  5737. with Formatted_Output_File;
  5738. with Macro;
  5739. with Parse;
  5740. with Variable;
  5741. with Input_File;
  5742. package body Word_Processor is
  5743.  
  5744. --| Notes (none)
  5745. --|
  5746. --| Modifications
  5747. --| 08/16/89  Rick Conn    Initial Version
  5748. --| 02/26/90  Rick Conn    Add Disable Underlining Flag
  5749. --| 02/26/90  Rick Conn    Remove trailing spaces from variables
  5750.  
  5751.   use Command;                                   -- for visibility of "="
  5752.   use Command_Symbols;
  5753.   use Formatted_Output_File;
  5754.   use Macro;
  5755.  
  5756.   Max_Line_Length
  5757.     : constant
  5758.       := 400;
  5759.  
  5760.   Output_File
  5761.     : Formatted_Output_File.File;
  5762.  
  5763.   Is_Open
  5764.     : BOOLEAN
  5765.       := false;
  5766.  
  5767.   Last_Line_Was_Blank
  5768.     : BOOLEAN
  5769.       := true;
  5770.  
  5771.   package Cmd
  5772.     renames Command;
  5773.  
  5774.   package Csym
  5775.     renames Command_Symbols;
  5776.  
  5777.   package Fof
  5778.     renames Formatted_Output_File;
  5779.  
  5780.   -- ..................................
  5781.   -- .                                .
  5782.   -- .  Expand                        .  SPEC & BODY
  5783.   -- .                                .
  5784.   -- ..................................
  5785.  
  5786.   procedure Expand
  5787.     ( In_Out_Line    : in out STRING;
  5788.       Last           : in out NATURAL ) is
  5789.  
  5790.   --| Purpose
  5791.   --| Expand expands the line in the buffer Inline, expanding tabs into
  5792.   --| spaces, replacing number register references with the appropriate
  5793.   --| values, and replacing variable name references with the appropriate
  5794.   --| values.  The result is placed back into Inline and Inlast.
  5795.   --| This procedure is internal to Wp_Body.
  5796.   --|
  5797.   --| Exceptions (none)
  5798.   --| Notes (not done)
  5799.  
  5800.     Temp
  5801.       : STRING (1 .. In_Out_Line'Length);
  5802.  
  5803.     Temp_Last
  5804.       : NATURAL
  5805.         := 0;
  5806.  
  5807.     Var
  5808.       : STRING (1 .. In_Out_Line'Length);
  5809.  
  5810.     Var_Last
  5811.       : NATURAL;
  5812.  
  5813.     Result_Last
  5814.       : NATURAL;
  5815.  
  5816.     Rover
  5817.       : NATURAL
  5818.         := In_Out_Line'First;
  5819.  
  5820.     type EXPANSION_STATE is
  5821.       ( IN_TEXT, IN_ESCAPE, IN_BRACED_VARIABLE, IN_VARIABLE );
  5822.  
  5823.     Current_State
  5824.       : EXPANSION_STATE
  5825.         := IN_TEXT;
  5826.  
  5827.       -- ..................................
  5828.       -- .                                .
  5829.       -- .  Expand.Expand_Variable        .  SPEC & BODY
  5830.       -- .                                .
  5831.       -- ..................................
  5832.  
  5833.     procedure Expand_Variable is
  5834.  
  5835.     --| Purpose
  5836.     --| Expand_Variable locates the current variable and places
  5837.     --| its value into the output.
  5838.     --|
  5839.     --| Exceptions (none)
  5840.     --| Notes (none)
  5841.  
  5842.       Value
  5843.         : STRING (1 .. In_Out_Line'Length);
  5844.  
  5845.       Value_Last
  5846.         : NATURAL;
  5847.  
  5848.       Value_First
  5849.         : NATURAL;
  5850.  
  5851.       Value_Last_Temp
  5852.         : NATURAL;
  5853.  
  5854.     begin -- Expand_Variable
  5855.  
  5856.       if (Var_Last = 2) then
  5857.         if (Var(1) = 'n') and (Var(2) in Variable.Nreg) then
  5858.           Variable.Nr(Var(2), Value, Value_Last);
  5859.         else
  5860.           Variable.Var(Var(1 .. Var_Last), Value, Value_Last);
  5861.         end if;
  5862.       else
  5863.         Variable.Var(Var(1 .. Var_Last), Value, Value_Last);
  5864.       end if;
  5865.       if Value_Last > 0 then
  5866.         Value_Last_Temp := 0;
  5867.         for I in reverse 1 .. Value_Last loop
  5868.         -- remove trailing spaces
  5869.           if Value(I) > ' ' then
  5870.             Value_Last_Temp := I;
  5871.             exit;
  5872.           end if;
  5873.         end loop;
  5874.         Value_Last     := Value_Last_Temp;
  5875.         Value_First := Value_Last + 1;
  5876.         for I in 1 .. Value_Last loop
  5877.         -- remove leading spaces
  5878.           if Value(I) > ' ' then
  5879.             Value_First := I;
  5880.             exit;
  5881.           end if;
  5882.         end loop;
  5883.         for I in Value_First .. Value_Last loop
  5884.           Temp_Last      := Temp_Last + 1;
  5885.           Temp(Temp_Last) := Value(I);
  5886.         end loop;
  5887.       else
  5888.         Error_Log.Write_Error(Error_Variable_Name);
  5889.       end if;
  5890.  
  5891.     end Expand_Variable;
  5892.  
  5893.     -- ..................................
  5894.     -- .                                .
  5895.     -- .  Expand.Process_In_Text        .  SPEC & BODY
  5896.     -- .                                .
  5897.     -- ..................................
  5898.     procedure Process_In_Text
  5899.       ( Index          : in NATURAL ) is
  5900.  
  5901.     --| Purpose
  5902.     --| Process_In_Text performs the character processing and state
  5903.     --| switching required when the Current_State is processing a
  5904.     --| text character as opposed to a variable character.  This can
  5905.     --| happen in any of the three EXPANSION_STATEs.
  5906.     --|
  5907.     --| Exceptions (none)
  5908.     --| Notes (none)
  5909.  
  5910.     begin -- Process_In_Text
  5911.  
  5912.       if In_Out_Line(Index) = Ascii.Ht then
  5913.         Temp_Last      := Temp_Last + 1;
  5914.         Temp(Temp_Last) := ' ';
  5915.         while Temp_Last mod 8 /= 1 loop
  5916.           Temp_Last      := Temp_Last + 1;
  5917.           Temp(Temp_Last) := ' ';
  5918.         end loop;
  5919.       else
  5920.         if In_Out_Line(Index) = Variable.Fc then
  5921.           Current_State  := IN_VARIABLE;
  5922.           Var_Last       := 0;
  5923.         else
  5924.           if In_Out_Line(Index) = Variable.Ec then
  5925.             Current_State  := IN_ESCAPE;
  5926.           else
  5927.             Temp_Last      := Temp_Last + 1;
  5928.             Temp(Temp_Last) := In_Out_Line(Index);
  5929.           end if;
  5930.         end if;
  5931.       end if;
  5932.  
  5933.     end Process_In_Text;
  5934.  
  5935.   begin -- Expand
  5936.  
  5937.     for I in In_Out_Line'First .. Last loop
  5938.       case Current_State is
  5939.         when IN_ESCAPE =>
  5940.           Temp_Last      := Temp_Last + 1;
  5941.           Temp(Temp_Last) := In_Out_Line(I);
  5942.           Current_State  := IN_TEXT;
  5943.         when IN_TEXT =>
  5944.           Process_In_Text(I);
  5945.         when IN_BRACED_VARIABLE =>
  5946.           if In_Out_Line(I) = '}' then
  5947.             Expand_Variable;
  5948.             Current_State  := IN_TEXT;
  5949.           else
  5950.             Var_Last       := Var_Last + 1;
  5951.             Var(Var_Last)  := In_Out_Line(I);
  5952.           end if;
  5953.         when IN_VARIABLE =>
  5954.           if In_Out_Line(I) = '{' then
  5955.             Current_State  := IN_BRACED_VARIABLE;
  5956.           else
  5957.             if ((In_Out_Line(I) >= '0') and (In_Out_Line(I) <= '9'))
  5958.                 or ((In_Out_Line(I) >= 'a') and (In_Out_Line(I) <= 'z'))
  5959.                 or ((In_Out_Line(I) >= 'A') and (In_Out_Line(I) <= 'Z'))
  5960.                 then
  5961.               Var_Last       := Var_Last + 1;
  5962.               Var(Var_Last)  := In_Out_Line(I);
  5963.             else
  5964.               Expand_Variable;
  5965.               Current_State  := IN_TEXT;
  5966.               Process_In_Text(I);
  5967.             end if;
  5968.           end if;
  5969.       end case;
  5970.     end loop;
  5971.     if (Current_State = IN_VARIABLE) or (Current_State = IN_BRACED_VARIABLE)
  5972.         then
  5973.       Expand_Variable;
  5974.     end if;
  5975.     Result_Last    := In_Out_Line'First + Temp_Last - 1;
  5976.     In_Out_Line(In_Out_Line'First .. Result_Last) := Temp(1 .. Temp_Last);
  5977.     Last           := In_Out_Line'First - 1;
  5978.     for I in reverse In_Out_Line'First .. Result_Last loop
  5979.       if In_Out_Line(I) > ' ' then
  5980.         Last           := I;
  5981.         exit;
  5982.       end if;
  5983.     end loop;
  5984.  
  5985.   exception -- Expand
  5986.     when others =>
  5987.       Error_Log.Write_Error(Error_Expansion);
  5988.  
  5989.   end Expand;
  5990.  
  5991.   -- ..................................
  5992.   -- .                                .
  5993.   -- .  Open_Output_File              .  BODY
  5994.   -- .                                .
  5995.   -- ..................................
  5996.   function Open_Output_File
  5997.     ( File_Name           : in STRING;
  5998.       Page_Offset         : in NATURAL;
  5999.       Disable_Bolding     : in BOOLEAN;
  6000.       Disable_Underlining : in BOOLEAN )
  6001.       return Operation_Status is
  6002.  
  6003.   --| Notes (none)
  6004.  
  6005.     Result
  6006.       : Fof.Status;
  6007.  
  6008.     Returned_Result
  6009.       : Operation_Status
  6010.         := Ok;
  6011.  
  6012.   begin -- Open_Output_File
  6013.  
  6014.     if not Is_Open then
  6015.       Fof.Open(Output_File, File_Name, Result);
  6016.       if Result = Fof.Not_Ok then
  6017.         Returned_Result := Not_Ok;
  6018.       else
  6019.         Is_Open        := true;
  6020.         Returned_Result := Ok;
  6021.         Fof.Set_Page_Attribute(Output_File, Fof.Page_Offset, Page_Offset);
  6022.         if Disable_Bolding then
  6023.           Command.Disable_Bolding;
  6024.         end if;
  6025.         if Disable_Underlining then
  6026.           Command.Disable_Underlining;
  6027.         end if;
  6028.       end if;
  6029.     else
  6030.       Returned_Result := Not_Ok;
  6031.     end if;
  6032.     return Returned_Result;
  6033.  
  6034.   exception
  6035.     when others =>
  6036.       Error_Log.Write_Error(Error_Internal_Open);
  6037.       return Not_Ok;
  6038.  
  6039.   end Open_Output_File;
  6040.  
  6041.   -- ..................................
  6042.   -- .                                .
  6043.   -- .  Process_Source_File           .  BODY
  6044.   -- .                                .
  6045.   -- ..................................
  6046.   function Process_Source_File
  6047.     ( File_Name      : in STRING )
  6048.       return Operation_Status is
  6049.  
  6050.   --| Notes (none)
  6051.  
  6052.     File_Id
  6053.       : Input_File.File_Type;
  6054.  
  6055.     Result
  6056.       : Operation_Status
  6057.         := Ok;
  6058.  
  6059.     My_Cmd
  6060.       : Csym.Command_Id;
  6061.  
  6062.     My_Macro
  6063.       : Macro.Macro_Id;
  6064.  
  6065.     Mresult
  6066.       : Macro.Macro_Status;
  6067.  
  6068.     subtype LINE is
  6069.       STRING (1 .. Max_Line_Length);
  6070.  
  6071.     Inline
  6072.       : LINE;
  6073.  
  6074.     Inlast
  6075.       : NATURAL;
  6076.  
  6077.     Verb
  6078.       : LINE;
  6079.  
  6080.     Cvlast
  6081.       : NATURAL;
  6082.  
  6083.     Tail
  6084.       : LINE;
  6085.  
  6086.     Ctlast
  6087.       : NATURAL;
  6088.  
  6089.     Current_Line_Number
  6090.       : NATURAL;
  6091.  
  6092.     type OPERATIONAL_STATE is
  6093.       ( IN_MACRO, IN_TEXT );
  6094.  
  6095.     State
  6096.       : OPERATIONAL_STATE
  6097.         := IN_TEXT;
  6098.  
  6099.       -- ..................................
  6100.       -- .                                .
  6101.       -- .  Process_Source_File.Is_Blank  .  BODY
  6102.       -- .                                .
  6103.       -- ..................................
  6104.  
  6105.     function Is_Blank
  6106.       ( Item           : in STRING )
  6107.         return BOOLEAN is
  6108.  
  6109.     --| Purpose
  6110.     --| Is_Blank determines if the indicated string contains any
  6111.     --| non-white characters.
  6112.     --|
  6113.     --| Exceptions (none)
  6114.     --| Notes (none)
  6115.  
  6116.       Result
  6117.         : BOOLEAN
  6118.           := true;
  6119.  
  6120.     begin -- Is_Blank
  6121.  
  6122.       for I in Item'range loop
  6123.         if Item(I) > ' ' then
  6124.           Result         := false;
  6125.           exit;
  6126.         end if;
  6127.       end loop;
  6128.       return Result;
  6129.  
  6130.     end Is_Blank;
  6131.  
  6132.   begin -- Process_Source_File
  6133.  
  6134.     begin
  6135.       Input_File.Open(File_Id, File_Name);
  6136.     exception
  6137.       when others =>
  6138.         Result         := Not_Ok;
  6139.     end;
  6140.     Variable.Set_File_Name(File_Name);
  6141.  
  6142.     if Result = Ok then
  6143.  
  6144.       while (not Input_File.End_Of_File(File_Id)) or (State = IN_MACRO) loop
  6145.         if State = IN_TEXT then
  6146.           Input_File.Get_Line(File_Id, Inline, Inlast);
  6147.           Variable.Increment_Line_Number;
  6148.         else
  6149.           if not Macro.Is_Empty(My_Macro) then
  6150.             Macro.Read(My_Macro, Inline, Inlast);
  6151.           else
  6152.             Macro.Close(My_Macro);
  6153.             State          := IN_TEXT;
  6154.             exit when Input_File.End_Of_File(File_Id);
  6155.             Input_File.Get_Line(File_Id, Inline, Inlast);
  6156.             Variable.Increment_Line_Number;
  6157.           end if;
  6158.         end if;
  6159.         if Inlast > 0 and then not Is_Blank(Inline(1 .. Inlast)) then
  6160.         -- Line is not blank
  6161.           Expand(Inline, Inlast);
  6162.           if Inline(1) /= Variable.Cc then
  6163.           -- Line is not a dot command
  6164.             if Variable.Is_Auto_Paragraph then
  6165.               if Last_Line_Was_Blank or (Inline(1) <= ' ') then
  6166.                 Fof.Skip(Output_File, 1);
  6167.                 Cmd.Process(Csym.Temporary_Indent, "+5", Output_File,
  6168.                     File_Id);
  6169.               end if;
  6170.             end if;
  6171.             Fof.Put_Line(Output_File, Inline(1 .. Inlast));
  6172.             if Variable.Bold_Count > 0 then
  6173.               Variable.Set_Bold_Count(Variable.Bold_Count - 1);
  6174.               if Variable.Bold_Count = 0 then
  6175.                 Fof.Set_Line_Attribute(Output_File, Fof.Bold, Fof.Off);
  6176.               end if;
  6177.             end if;
  6178.             if Variable.Bold_Count > 0 then
  6179.               Variable.Set_Bold_Count(Variable.Bold_Count - 1);
  6180.               if Variable.Bold_Count = 0 then
  6181.                 Fof.Set_Line_Attribute(Output_File, Fof.Bold, Fof.Off);
  6182.               end if;
  6183.             end if;
  6184.             if Variable.Center_Count > 0 then
  6185.               Variable.Set_Center_Count(Variable.Center_Count - 1);
  6186.               if Variable.Center_Count = 0 then
  6187.                 Fof.Set_Line_Attribute(Output_File, Fof.Center, Fof.Off);
  6188.               end if;
  6189.             end if;
  6190.             if Variable.Underline_Count > 0 then
  6191.               Variable.Set_Underline_Count(Variable.Underline_Count - 1);
  6192.               if Variable.Underline_Count = 0 then
  6193.                 Fof.Set_Line_Attribute(Output_File, Fof.Underline, Fof.Off);
  6194.               end if;
  6195.             end if;
  6196.           else
  6197.           -- Line is a dot command
  6198.             Parse(Inline(2 .. Inlast), Verb, Tail, Cvlast, Ctlast);
  6199.             if Macro.Locate(Verb(1 .. Cvlast)) = Macro.Ok then
  6200.               Macro.Open(Verb(1 .. Cvlast), My_Macro, Mresult);
  6201.               if Mresult = Macro.Ok then
  6202.                 State          := IN_MACRO;
  6203.               end if;
  6204.               Macro.Define_Parameters(Verb(1 .. Cvlast), Tail(1 .. Ctlast));
  6205.             else
  6206.               My_Cmd         := Cmd.Identify(Verb(1 .. Cvlast));
  6207.               if My_Cmd /= Csym.Unknown then
  6208.                 if My_Cmd = Csym.Include then
  6209.                   Current_Line_Number := Variable.Line_Number;
  6210.                 end if;
  6211.                 Cmd.Process(My_Cmd, Tail(1 .. Ctlast), Output_File, File_Id);
  6212.                 if My_Cmd = Csym.Include then
  6213.                   Variable.Set_File_Name(File_Name);
  6214.                   Variable.Set_Line_Number(Current_Line_Number);
  6215.                 end if;
  6216.               else
  6217.                 Error_Log.Write_Error(Error_Unknown);
  6218.               end if;
  6219.             end if;
  6220.           end if;
  6221.           Last_Line_Was_Blank := false;
  6222.         else
  6223.         -- Line is blank
  6224.           if Fof.Get_Line_Attribute(Output_File, Fof.Fill) = Fof.Off then
  6225.             Fof.Put_Line(Output_File, "");
  6226.           end if;
  6227.           Last_Line_Was_Blank := true;
  6228.           if Variable.Bold_Count > 0 then
  6229.             Variable.Set_Bold_Count(Variable.Bold_Count - 1);
  6230.             if Variable.Bold_Count = 0 then
  6231.               Fof.Set_Line_Attribute(Output_File, Fof.Bold, Fof.Off);
  6232.             end if;
  6233.           end if;
  6234.           if Variable.Center_Count > 0 then
  6235.             Variable.Set_Center_Count(Variable.Center_Count - 1);
  6236.             if Variable.Center_Count = 0 then
  6237.               Fof.Set_Line_Attribute(Output_File, Fof.Center, Fof.Off);
  6238.             end if;
  6239.           end if;
  6240.           if Variable.Underline_Count > 0 then
  6241.             Variable.Set_Underline_Count(Variable.Underline_Count - 1);
  6242.             if Variable.Underline_Count = 0 then
  6243.               Fof.Set_Line_Attribute(Output_File, Fof.Underline, Fof.Off);
  6244.             end if;
  6245.           end if;
  6246.         end if;
  6247.       end loop;
  6248.       Input_File.Close(File_Id);
  6249.  
  6250.     end if;
  6251.  
  6252.     return Result;
  6253.  
  6254.   exception
  6255.     when others =>
  6256.       return Not_Ok;
  6257.  
  6258.   end Process_Source_File;
  6259.  
  6260.   -- ..................................
  6261.   -- .                                .
  6262.   -- .  Close_Output_File             .  BODY
  6263.   -- .                                .
  6264.   -- ..................................
  6265.   procedure Close_Output_File is
  6266.  
  6267.   --| Notes (none)
  6268.  
  6269.   begin -- Close_Output_File
  6270.  
  6271.     Fof.Close(Output_File);
  6272.     Is_Open        := false;
  6273.  
  6274.   end Close_Output_File;
  6275.  
  6276. end Word_Processor;
  6277.